@supcoflow/chat 1.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/orca.txt +25 -0
- package/README.md +125 -47
- package/dist/apariencia.d.ts +16 -0
- package/dist/apariencia.d.ts.map +1 -0
- package/dist/cliente.d.ts +25 -0
- package/dist/cliente.d.ts.map +1 -0
- package/dist/componentes/Adjuntos.d.ts +11 -0
- package/dist/componentes/Adjuntos.d.ts.map +1 -0
- package/dist/componentes/Burbuja.d.ts +6 -0
- package/dist/componentes/Burbuja.d.ts.map +1 -0
- package/dist/componentes/Compositor.d.ts +19 -0
- package/dist/componentes/Compositor.d.ts.map +1 -0
- package/dist/componentes/Markdown.d.ts +4 -0
- package/dist/componentes/Markdown.d.ts.map +1 -0
- package/dist/componentes/Mensajes.d.ts +8 -0
- package/dist/componentes/Mensajes.d.ts.map +1 -0
- package/dist/componentes/Panel.d.ts +11 -0
- package/dist/componentes/Panel.d.ts.map +1 -0
- package/dist/componentes/PreguntaHitl.d.ts +8 -0
- package/dist/componentes/PreguntaHitl.d.ts.map +1 -0
- package/dist/componentes/Widget.d.ts +21 -0
- package/dist/componentes/Widget.d.ts.map +1 -0
- package/dist/contexto.d.ts +10 -0
- package/dist/contexto.d.ts.map +1 -0
- package/dist/estado-del-widget.d.ts +18 -37
- package/dist/estado-del-widget.d.ts.map +1 -1
- package/dist/estado.d.ts +40 -0
- package/dist/estado.d.ts.map +1 -0
- package/dist/evidencia/adjuntos.d.ts +45 -0
- package/dist/evidencia/adjuntos.d.ts.map +1 -0
- package/dist/evidencia/captura.d.ts +56 -0
- package/dist/evidencia/captura.d.ts.map +1 -0
- package/dist/evidencia/elemento.d.ts +46 -0
- package/dist/evidencia/elemento.d.ts.map +1 -0
- package/dist/evidencia/extraer-elemento.d.ts +11 -0
- package/dist/evidencia/extraer-elemento.d.ts.map +1 -0
- package/dist/evidencia/resumen-de-evidencia.d.ts +11 -0
- package/dist/evidencia/resumen-de-evidencia.d.ts.map +1 -0
- package/dist/evidencia/selector-de-elementos.d.ts +11 -0
- package/dist/evidencia/selector-de-elementos.d.ts.map +1 -0
- package/dist/evidencia/subida.d.ts +17 -0
- package/dist/evidencia/subida.d.ts.map +1 -0
- package/dist/iife.d.ts +2 -0
- package/dist/iife.d.ts.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -2
- package/dist/index.js.map +7 -1
- package/dist/markdown.d.ts +31 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/montar.d.ts +9 -0
- package/dist/montar.d.ts.map +1 -0
- package/dist/opciones.d.ts +80 -0
- package/dist/opciones.d.ts.map +1 -0
- package/dist/protocolo.d.ts +61 -0
- package/dist/protocolo.d.ts.map +1 -0
- package/dist/react.d.ts +11 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/sesion-guardada.d.ts +5 -0
- package/dist/sesion-guardada.d.ts.map +1 -0
- package/dist/tema.d.ts +3 -0
- package/dist/tema.d.ts.map +1 -0
- package/dist/textos.d.ts +32 -0
- package/dist/textos.d.ts.map +1 -0
- package/dist/widget.iife.js +91 -0
- package/dist/widget.iife.js.map +7 -0
- package/package.json +14 -33
- package/CHANGELOG.md +0 -24
- package/dist/ChatDeIntake.d.ts +0 -11
- package/dist/ChatDeIntake.d.ts.map +0 -1
- package/dist/ChatDeIntake.js +0 -56
- package/dist/ChatDeIntake.js.map +0 -1
- package/dist/estado-del-widget.js +0 -46
- package/dist/estado-del-widget.js.map +0 -1
- package/dist/partes-visibles.d.ts +0 -16
- package/dist/partes-visibles.d.ts.map +0 -1
- package/dist/partes-visibles.js +0 -14
- package/dist/partes-visibles.js.map +0 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Orca — github.com/stablyai/orca
|
|
2
|
+
Código trasladado a TypeScript en packages/widget/src/evidencia/extraer-elemento.ts y
|
|
3
|
+
selector-de-elementos.ts (src/main/browser/grab-guest-*.ts del original).
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026 Lovecast Inc.
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,72 +1,150 @@
|
|
|
1
1
|
# @supcoflow/chat
|
|
2
2
|
|
|
3
|
-
El chat de intake de Supcoflow,
|
|
4
|
-
|
|
5
|
-
reporte en Supcoflow.
|
|
6
|
-
|
|
7
|
-
## Requisitos
|
|
8
|
-
|
|
9
|
-
- **React 19** (`peerDependencies: react >=19`).
|
|
10
|
-
- **Node 24 o mayor** en el entorno donde se instala y se hace el build: el transporte es
|
|
11
|
-
[`eve`](https://eve.dev), que lo exige. Con Node 22 o 23, `npm install` avisa por `engines`.
|
|
12
|
-
- Un bundler (Next, Vite, webpack): el paquete emite ESM con imports relativos sin extensión.
|
|
13
|
-
- Un proyecto de Supcoflow con **el chat activado**. La sección `sdk` del proyecto en la consola
|
|
14
|
-
tiene el checklist de lo que falta.
|
|
3
|
+
El chat de intake de Supcoflow, embebible en cualquier sitio. Conversa con un asistente que
|
|
4
|
+
orienta sobre el producto y, cuando hay un bug de verdad, abre un reporte en Supcoflow.
|
|
15
5
|
|
|
16
6
|
## Instalación
|
|
17
7
|
|
|
8
|
+
### Con npm (React, Vue, Svelte, vanilla)
|
|
9
|
+
|
|
18
10
|
```bash
|
|
19
11
|
npm i @supcoflow/chat
|
|
20
12
|
```
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
como deuda y se va a separar en un paquete cliente liviano). `ai` entra solo como peer de `eve`.
|
|
24
|
-
No hace falta `transpilePackages` en `next.config`.
|
|
25
|
-
|
|
26
|
-
## Uso
|
|
14
|
+
En React:
|
|
27
15
|
|
|
28
16
|
```tsx
|
|
29
17
|
import { ChatDeIntake } from "@supcoflow/chat";
|
|
30
18
|
|
|
31
|
-
<ChatDeIntake
|
|
32
|
-
tenantId="tnt_xxx"
|
|
33
|
-
projectId="proj_xxx"
|
|
34
|
-
backendUrl="https://chat.supcoflow.dev"
|
|
35
|
-
/>
|
|
19
|
+
<ChatDeIntake tenantId="tnt_xxx" projectId="proj_xxx" />
|
|
36
20
|
```
|
|
37
21
|
|
|
38
|
-
|
|
39
|
-
lista de orígenes admitidos del proyecto más el tope de mensajes (ventana rodante de 24 h), los
|
|
40
|
-
dos del lado del motor. Poner el `tenantId` en el HTML de un sitio público es el uso previsto.
|
|
22
|
+
Sin React:
|
|
41
23
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
sección `sdk` de la consola tiene el snippet).
|
|
24
|
+
```ts
|
|
25
|
+
import { montarChat } from "@supcoflow/chat";
|
|
45
26
|
|
|
46
|
-
|
|
27
|
+
const chat = montarChat(document.body, { tenantId: "tnt_xxx", projectId: "proj_xxx" });
|
|
28
|
+
// chat.desmontar() cuando haga falta
|
|
29
|
+
```
|
|
47
30
|
|
|
48
|
-
|
|
49
|
-
nunca — es la causa más común de «lo instalé y no aparece»:
|
|
31
|
+
### Con una línea de `<script>` (WordPress, Webflow, HTML plano)
|
|
50
32
|
|
|
33
|
+
```html
|
|
34
|
+
<script src="https://chat.supcoflow.dev/widget.js" data-tenant="tnt_xxx" data-project="proj_xxx" defer></script>
|
|
51
35
|
```
|
|
52
|
-
|
|
36
|
+
|
|
37
|
+
Opciones por atributo: `data-backend`, `data-posicion` (`derecha`|`izquierda`), `data-titulo`,
|
|
38
|
+
`data-acento` (color), `data-version-app`, `data-contexto-automatico="false"`, `data-usuario-id`,
|
|
39
|
+
`data-usuario-rol`. También queda `window.SupcoflowChat.montar(opciones)` / `.desmontar()`.
|
|
40
|
+
|
|
41
|
+
Los identificadores **son públicos** (modelo DSN). La contención es la lista de Origins admitidos
|
|
42
|
+
del proyecto más el tope de mensajes, los dos del lado de Supcoflow.
|
|
43
|
+
|
|
44
|
+
## Opciones
|
|
45
|
+
|
|
46
|
+
| opción | default | qué |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `backendUrl` | `https://chat.supcoflow.dev` | el backend del chat |
|
|
49
|
+
| `modo` | `"burbuja"` | `"burbuja"` (botón flotante + panel) o `"inline"` (el panel donde lo montes) |
|
|
50
|
+
| `posicion` | `"derecha"` | lado de la burbuja |
|
|
51
|
+
| `titulo` | `"Ayuda"` | cabecera del panel |
|
|
52
|
+
| `tema` | neutro | `{ acento, fondo, texto, textoSuave, radio, fuente }`, cualquier subconjunto |
|
|
53
|
+
| `contexto` | `{}` | `{ versionApp }` — viaja con el primer mensaje |
|
|
54
|
+
| `contextoAutomatico` | `true` | manda la URL (sin query) y el navegador. Errores de consola: nunca |
|
|
55
|
+
| `onDiagnostico` | — | `({ visible, status, motivo }) => void`, ver abajo |
|
|
56
|
+
| `usuario` | — | `{ id, rol, atributos }` — quién es el usuario según tu app, para el diagnóstico. Ver abajo |
|
|
57
|
+
| `previewToken` | — | **interna**: la usa la consola de Supcoflow para el preview; en tu sitio no hace nada útil |
|
|
58
|
+
|
|
59
|
+
## Quién es el usuario
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
<ChatDeIntake tenantId="tnt_xxx" projectId="proj_xxx" usuario={{ id: "u_123", rol: "admin", atributos: { plan: "pro" } }} />
|
|
53
63
|
```
|
|
54
64
|
|
|
55
|
-
|
|
65
|
+
Todo opcional. `id` (hasta 100 caracteres), `rol` (60) y hasta 8 `atributos` (claves de 40, valores de
|
|
66
|
+
200) viajan con el primer mensaje al asistente y, si se abre un reporte, al reporte: el rol es el
|
|
67
|
+
dato de diagnóstico más barato que hay (la mitad de los «no me aparece el botón» son permisos). Es
|
|
68
|
+
**declarado, no verificado**: no da permisos a nada, es contexto. Lo que se pasa de largo se
|
|
69
|
+
recorta; lo que no sea `id`, `rol` o `atributos` se descarta.
|
|
70
|
+
|
|
71
|
+
No hay `nombre` en esta versión: llega con la pantalla de inicio, que es lo único que lo va a usar,
|
|
72
|
+
y **nunca va a viajar** al asistente ni al reporte.
|
|
73
|
+
|
|
74
|
+
## La marca desde la consola
|
|
75
|
+
|
|
76
|
+
El logo, el título y los colores del chat se editan desde `/proyectos/<slug>/sdk` en Supcoflow y el
|
|
77
|
+
widget los aplica solo, antes del primer dibujo. Lo que pases por código (`titulo`, `tema`) gana
|
|
78
|
+
sobre lo guardado en la consola, campo a campo.
|
|
79
|
+
|
|
80
|
+
## Qué pasa cuando algo falla
|
|
81
|
+
|
|
82
|
+
**Al cargar**, si el chat del proyecto está apagado, el tope del día se agotó, el origen del
|
|
83
|
+
sitio no está admitido o el backend no contesta, el widget **no se dibuja**: quien está del otro
|
|
84
|
+
lado es un usuario final del producto, y no tiene nada que hacer con «el proyecto tiene el tope
|
|
85
|
+
agotado». Para saber por qué no aparece, pasá `onDiagnostico` o mirá la consola en `localhost`:
|
|
86
|
+
|
|
87
|
+
| `status` | `motivo` | qué hacer |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| 403 | `chat_deshabilitado` | activar el chat en `/proyectos/<slug>/sdk` |
|
|
90
|
+
| 403 | `origen_no_admitido` | agregar el origen del sitio en esa misma pantalla |
|
|
91
|
+
| 404 | `proyecto_desconocido` | revisar `tenantId` / `projectId` |
|
|
92
|
+
| 429 | `tope_de_mensajes` | esperar: el tope vuelve a abrir solo |
|
|
93
|
+
| 502 | `motor_inalcanzable` | es del lado de Supcoflow |
|
|
94
|
+
| 0 | `sin_respuesta` | red, CSP o `backendUrl` mal escrita |
|
|
95
|
+
|
|
96
|
+
**A mitad de conversación**, un error se muestra debajo del último mensaje con un botón de
|
|
97
|
+
reintentar, y lo que el usuario escribió se conserva. `onDiagnostico` lo recibe también, con el
|
|
98
|
+
código del error en `motivo`.
|
|
99
|
+
|
|
100
|
+
## Lo que el widget hace y no hace
|
|
101
|
+
|
|
102
|
+
- La conversación sobrevive a una recarga **de la misma pestaña**.
|
|
103
|
+
- El asistente escribe con formato (negrita, listas, código, links) y pide la confirmación del
|
|
104
|
+
reporte con botones.
|
|
105
|
+
- El navegador habla sólo con el backend del chat, en un formato propio y chico; el motor de
|
|
106
|
+
agentes queda del lado del servidor.
|
|
107
|
+
- No le da seguimiento del reporte al que reportó. Es a propósito.
|
|
108
|
+
- No recolecta errores de consola ni nada que no esté en la tabla de opciones.
|
|
109
|
+
- Señalar, capturar y adjuntar son acciones del usuario: el widget no captura nada solo.
|
|
110
|
+
|
|
111
|
+
## Señalar y adjuntar
|
|
112
|
+
|
|
113
|
+
El usuario final puede **señalar el elemento** de tu página que le falla, **capturar la pantalla**
|
|
114
|
+
y **adjuntar una imagen**. Eso viaja al reporte (y al agente que lo arregla), nunca al modelo del
|
|
115
|
+
chat, que sólo recibe una descripción corta («señaló el botón Guardar del formulario»).
|
|
116
|
+
|
|
117
|
+
Qué se recolecta al señalar, y qué no:
|
|
118
|
+
|
|
119
|
+
- Sí: la etiqueta, un selector CSS, la ruta en el DOM, el texto visible, los atributos `id class
|
|
120
|
+
name type role href src alt title placeholder for action method` y `aria-*`, dieciséis
|
|
121
|
+
propiedades de estilo, el texto de los elementos vecinos, y el HTML del elemento acotado a 4 KB.
|
|
122
|
+
- No: **el valor de ningún `input`, `textarea` o `select`**, ningún `<script>`, ninguna query ni
|
|
123
|
+
hash de URL; y cualquier atributo o clase con pinta de secreto (`access_token`, `csrf`,
|
|
124
|
+
`password`…) se reemplaza por `[redacted]`.
|
|
125
|
+
|
|
126
|
+
La captura la toma el usuario con el diálogo del navegador (`getDisplayMedia`) y la ve como
|
|
127
|
+
miniatura antes de que suba; puede quitarla. Algunos navegadores y iOS no soportan
|
|
128
|
+
`getDisplayMedia`: ahí sólo queda «Adjuntar imagen», que funciona en todos lados. Las imágenes se re-codifican
|
|
129
|
+
(WebP o PNG, hasta 1,5 MB) y no conservan metadatos del archivo original. Hasta **4 adjuntos por
|
|
130
|
+
conversación**.
|
|
131
|
+
|
|
132
|
+
Quien señala ve un resaltado sobre tu página: es un overlay nuestro, a pantalla completa, que se
|
|
133
|
+
desmonta al elegir o al apretar Esc. El código del selector es de [Orca](https://github.com/stablyai/orca)
|
|
134
|
+
(MIT), trasladado a TypeScript; la licencia va en `LICENSES/orca.txt`.
|
|
135
|
+
|
|
136
|
+
## Si tu sitio tiene CSP
|
|
137
|
+
|
|
138
|
+
`connect-src` tiene que admitir el `backendUrl` (por defecto `https://chat.supcoflow.dev`). El
|
|
139
|
+
widget no carga fuentes ni scripts de terceros. Las miniaturas de las capturas son `data:` URLs
|
|
140
|
+
generadas en el navegador: si tu `img-src` no admite `data:`, no se ven las miniaturas (la subida
|
|
141
|
+
funciona igual).
|
|
142
|
+
|
|
143
|
+
## Tamaño y requisitos
|
|
56
144
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
lado es un usuario final del producto del cliente. Para diagnosticar, mirá el status de
|
|
60
|
-
`GET {backendUrl}/api/chat/estado?tenant_id=…&project_id=…` **desde el sitio** (el origen
|
|
61
|
-
importa): 403 (chat apagado u origen no admitido), 429 (tope agotado), 404 (proyecto
|
|
62
|
-
desconocido), 502 (backend sin poder hablar con el motor). O usá «probar la instalación» en la
|
|
63
|
-
sección `sdk` de la consola. Ojo con `www.tu-sitio.com` contra `tu-sitio.com`: la comparación es
|
|
64
|
-
por origen exacto, y son dos entradas de la lista.
|
|
145
|
+
Un solo archivo por salida, sin dependencias que instalar. React es opcional (sólo para
|
|
146
|
+
`ChatDeIntake`). Sin webfonts. Funciona en navegadores con ES2022 y Shadow DOM.
|
|
65
147
|
|
|
66
|
-
##
|
|
148
|
+
## Licencias
|
|
67
149
|
|
|
68
|
-
|
|
69
|
-
- No le da seguimiento del reporte al que reportó. Es a propósito — el único lugar donde un
|
|
70
|
-
reporte se ve es la consola del operador.
|
|
71
|
-
- No trae estilos configurables todavía: el panel usa estilos en línea y hereda la tipografía del
|
|
72
|
-
sitio.
|
|
150
|
+
MIT. Ver `LICENSES/` por el código de terceros incluido.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type OpcionesDelChat, type TemaDelChat } from "./opciones";
|
|
2
|
+
/** La marca tal cual la manda el backend (`GET /api/chat/estado`, snake_case). Todo opcional: un
|
|
3
|
+
* backend viejo no la manda y el widget usa sus defaults — nunca se adivina, como con `motivo`. */
|
|
4
|
+
export interface MarcaDelMotor {
|
|
5
|
+
logo_url?: string | null;
|
|
6
|
+
titulo?: string | null;
|
|
7
|
+
saludo?: string | null;
|
|
8
|
+
tema?: Partial<TemaDelChat> | null;
|
|
9
|
+
}
|
|
10
|
+
export interface Apariencia {
|
|
11
|
+
titulo: string;
|
|
12
|
+
logoUrl: string | null;
|
|
13
|
+
tema: TemaDelChat;
|
|
14
|
+
}
|
|
15
|
+
export declare function resolverApariencia(o: Pick<OpcionesDelChat, "titulo" | "tema">, marca: unknown): Apariencia;
|
|
16
|
+
//# sourceMappingURL=apariencia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apariencia.d.ts","sourceRoot":"","sources":["../src/apariencia.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAWtF;mGACmG;AACnG,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,WAAW,CAAC;CACnB;AAoBD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,UAAU,CAQ1G"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OpcionesResueltas } from "./opciones";
|
|
2
|
+
import type { EventoDelWidget } from "./protocolo";
|
|
3
|
+
export type Respuesta = {
|
|
4
|
+
requestId: string;
|
|
5
|
+
optionId?: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
};
|
|
8
|
+
export interface ClienteDelChat {
|
|
9
|
+
abrir(mensaje: string, contexto: Record<string, string> | undefined): AsyncIterable<EventoDelWidget>;
|
|
10
|
+
/** `contexto` en un mensaje de seguimiento (Revisión 2 punto 5): el resumen acumulado de la
|
|
11
|
+
* evidencia va en CADA turno, porque clientContext de Eve es por turno. */
|
|
12
|
+
seguir(id: string, indice: number, cuerpo: {
|
|
13
|
+
mensaje: string;
|
|
14
|
+
contexto?: Record<string, string>;
|
|
15
|
+
} | {
|
|
16
|
+
respuesta: Respuesta;
|
|
17
|
+
}): AsyncIterable<EventoDelWidget>;
|
|
18
|
+
recuperar(id: string, desde: number): AsyncIterable<EventoDelWidget>;
|
|
19
|
+
}
|
|
20
|
+
/** Una línea que no es un evento v1 es `null`: el lector la salta y sigue. Un `t` desconocido
|
|
21
|
+
* SÍ pasa — es la regla de compatibilidad: el reducer lo ignora. */
|
|
22
|
+
export declare function parsearLinea(linea: string): EventoDelWidget | null;
|
|
23
|
+
export declare function leerNdjson(cuerpo: ReadableStream<Uint8Array>): AsyncGenerator<EventoDelWidget>;
|
|
24
|
+
export declare function crearCliente(o: OpcionesResueltas, fetchFn?: typeof fetch): ClienteDelChat;
|
|
25
|
+
//# sourceMappingURL=cliente.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliente.d.ts","sourceRoot":"","sources":["../src/cliente.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOnD,MAAM,MAAM,SAAS,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IACrG;+EAC2E;IAC3E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG;QAAE,SAAS,EAAE,SAAS,CAAA;KAAE,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9J,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;CACtE;AAED;oEACoE;AACpE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CASlE;AAED,wBAAuB,UAAU,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,eAAe,CAAC,CAqBrG;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,GAAE,OAAO,KAA6B,GAAG,cAAc,CAyChH"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Adjunto } from "../evidencia/adjuntos";
|
|
2
|
+
export declare function Adjuntos(props: {
|
|
3
|
+
adjuntos: Adjunto[];
|
|
4
|
+
ocupado: boolean;
|
|
5
|
+
aviso: string | null;
|
|
6
|
+
/** Se ofrece sólo si el ÚLTIMO adjunto es un elemento y el navegador sabe capturar (§3.2). */
|
|
7
|
+
onCapturarElemento: (() => void) | null;
|
|
8
|
+
onQuitar: (clave: number) => void;
|
|
9
|
+
onReintentar: (clave: number) => void;
|
|
10
|
+
}): import("preact").JSX.Element | null;
|
|
11
|
+
//# sourceMappingURL=Adjuntos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Adjuntos.d.ts","sourceRoot":"","sources":["../../src/componentes/Adjuntos.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAqBrD,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8FAA8F;IAC9F,kBAAkB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC,uCAsBA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Burbuja.d.ts","sourceRoot":"","sources":["../../src/componentes/Burbuja.tsx"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,SAAS,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,gCAgB1G"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface Herramientas {
|
|
2
|
+
onSenalar: () => void;
|
|
3
|
+
onCapturarPantalla: () => void;
|
|
4
|
+
onAdjuntarImagen: (archivo: File) => void;
|
|
5
|
+
/** §3.2: sin getDisplayMedia (Safari, iOS, http) el ítem de capturar NO se dibuja; adjuntar imagen siempre. */
|
|
6
|
+
puedeCapturar: boolean;
|
|
7
|
+
/** Falso con la cola llena (4): los botones se deshabilitan y el aviso lo dice la barra. */
|
|
8
|
+
puedeAdjuntar: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function Compositor(props: {
|
|
11
|
+
valor: string;
|
|
12
|
+
onCambio: (v: string) => void;
|
|
13
|
+
onEnviar: () => void;
|
|
14
|
+
deshabilitado: boolean;
|
|
15
|
+
enfocarAlMontar: boolean;
|
|
16
|
+
/** `null` en preview (§2 del diseño de la marca): ni botones ni input de archivo — la subida está apagada, no deshabilitada. */
|
|
17
|
+
herramientas: Herramientas | null;
|
|
18
|
+
}): import("preact").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=Compositor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Compositor.d.ts","sourceRoot":"","sources":["../../src/componentes/Compositor.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,gBAAgB,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC;IAC1C,+GAA+G;IAC/G,aAAa,EAAE,OAAO,CAAC;IACvB,4FAA4F;IAC5F,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,gIAAgI;IAChI,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC,gCAoEA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/componentes/Markdown.tsx"],"names":[],"mappings":"AA+BA,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,gCAEpD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Respuesta } from "../cliente";
|
|
2
|
+
import { type EstadoDelChat } from "../estado";
|
|
3
|
+
export declare function Mensajes(props: {
|
|
4
|
+
estado: EstadoDelChat;
|
|
5
|
+
onReintentar: () => void;
|
|
6
|
+
onResponder: (r: Respuesta) => void;
|
|
7
|
+
}): import("preact").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=Mensajes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Mensajes.d.ts","sourceRoot":"","sources":["../../src/componentes/Mensajes.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAKjE,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,MAAM,IAAI,CAAC;IAAC,WAAW,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAA;CAAE,gCA+BvH"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ComponentChildren } from "preact";
|
|
2
|
+
export declare function Panel(props: {
|
|
3
|
+
titulo: string;
|
|
4
|
+
logoUrl: string | null;
|
|
5
|
+
enPreview: boolean;
|
|
6
|
+
modo: "burbuja" | "inline";
|
|
7
|
+
posicion: "derecha" | "izquierda";
|
|
8
|
+
onMinimizar: () => void;
|
|
9
|
+
children: ComponentChildren;
|
|
10
|
+
}): import("preact").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=Panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../src/componentes/Panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAGhD,wBAAgB,KAAK,CAAC,KAAK,EAAE;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,QAAQ,EAAE,SAAS,GAAG,WAAW,CAAC;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B,gCAyBA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Respuesta } from "../cliente";
|
|
2
|
+
import type { PreguntaPendiente } from "../estado";
|
|
3
|
+
export declare function PreguntaHitl(props: {
|
|
4
|
+
pregunta: PreguntaPendiente;
|
|
5
|
+
ocupado: boolean;
|
|
6
|
+
onResponder: (r: Respuesta) => void;
|
|
7
|
+
}): import("preact").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=PreguntaHitl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreguntaHitl.d.ts","sourceRoot":"","sources":["../../src/componentes/PreguntaHitl.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAKnD,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAA;CAAE,gCAqCzH"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ClienteDelChat } from "../cliente";
|
|
2
|
+
import { type ErrorVisible } from "../estado";
|
|
3
|
+
import type { OpcionesResueltas } from "../opciones";
|
|
4
|
+
import type { CursorDeSesion } from "../protocolo";
|
|
5
|
+
export default function Widget(props: {
|
|
6
|
+
cliente: ClienteDelChat;
|
|
7
|
+
opciones: OpcionesResueltas;
|
|
8
|
+
/** De la marca del motor (§3.3); `null` = sin logo. */
|
|
9
|
+
logoUrl: string | null;
|
|
10
|
+
/** §2/§5.3 del diseño de la marca: rótulo en la cabecera y la evidencia apagada — en el preview no
|
|
11
|
+
* hay `chat_conversaciones` que la reciba, y una captura de pantalla del modal no tiene que
|
|
12
|
+
* confundirse con el chat real. */
|
|
13
|
+
enPreview: boolean;
|
|
14
|
+
cursorInicial: CursorDeSesion | null;
|
|
15
|
+
alCambiarCursor: (c: CursorDeSesion | null) => void;
|
|
16
|
+
alError: (e: ErrorVisible) => void;
|
|
17
|
+
abiertoAlInicio: boolean;
|
|
18
|
+
/** El host de nuestro shadow root: el selector no lo puede elegir (señalar el chat no es un bug del sitio). */
|
|
19
|
+
hostDelWidget: Element | null;
|
|
20
|
+
}): import("preact").JSX.Element | null;
|
|
21
|
+
//# sourceMappingURL=Widget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Widget.d.ts","sourceRoot":"","sources":["../../src/componentes/Widget.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAqG,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAQjJ,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,cAAc,CAAC;AAQpE,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE;IACpC,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,uDAAuD;IACvD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;uCAEmC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,cAAc,GAAG,IAAI,CAAC;IACrC,eAAe,EAAE,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACpD,OAAO,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,+GAA+G;IAC/G,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,uCAyOA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { OpcionesResueltas } from "./opciones";
|
|
2
|
+
export declare function resumenDeContexto(o: OpcionesResueltas, ventana: {
|
|
3
|
+
location?: {
|
|
4
|
+
href: string;
|
|
5
|
+
};
|
|
6
|
+
navigator?: {
|
|
7
|
+
userAgent: string;
|
|
8
|
+
};
|
|
9
|
+
}): Record<string, string> | undefined;
|
|
10
|
+
//# sourceMappingURL=contexto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contexto.d.ts","sourceRoot":"","sources":["../src/contexto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAapD,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,iBAAiB,EACpB,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,SAAS,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC1E,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAuBpC"}
|
|
@@ -1,46 +1,27 @@
|
|
|
1
|
+
import type { Diagnostico } from "./opciones";
|
|
1
2
|
export type Visibilidad = "visible" | "oculto";
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* fallback no necesita ser criptográfico: es un id de canal anónimo, no un secreto.
|
|
6
|
-
*
|
|
7
|
-
* `ChatDeIntake` dejó de llamar esta función: sobre `useEveAgent` el rol de identificar la
|
|
8
|
-
* conversación lo cumple el `sessionId` que pone el backend. Queda EXPORTADA sin llamador
|
|
9
|
-
* dentro de este paquete —no se borra especulativamente— porque `POST /api/chat`, el camino
|
|
10
|
-
* viejo, sigue vivo hasta el corte, y es la ruta que necesita el concepto de "id de canal" del
|
|
11
|
-
* lado del cliente. */
|
|
12
|
-
export declare function generarCanalId(): string;
|
|
13
|
-
/** Una barra final en `backendUrl` ("https://x.com/", la forma más natural de
|
|
14
|
-
* escribirlo) deja `//` duplicado en las URLs armadas más abajo: el motor responde con
|
|
15
|
-
* un 308 sin headers de CORS y el navegador lo bloquea sin explicar que el problema es
|
|
16
|
-
* la barra. Mismo patrón que `motor.ts` usa para su propia base URL. */
|
|
3
|
+
/** Una barra final en `backendUrl` ("https://x.com/", la forma más natural de escribirlo) deja
|
|
4
|
+
* `//` duplicado en las URLs armadas: el motor responde con un 308 sin headers de CORS y el
|
|
5
|
+
* navegador lo bloquea sin explicar que el problema es la barra. */
|
|
17
6
|
export declare function normalizarBackendUrl(backendUrl: string): string;
|
|
18
|
-
/** §
|
|
19
|
-
* Ocultarse es lo honesto: no hay nada que decirle al usuario final sobre el estado
|
|
20
|
-
* del proyecto de otra empresa. */
|
|
7
|
+
/** §2.4 del diseño: sin backend, sin tope, o ante cualquier duda, el widget NO se dibuja al
|
|
8
|
+
* montar. Ocultarse es lo honesto: no hay nada que decirle al usuario final sobre el estado
|
|
9
|
+
* interno del proyecto de otra empresa. */
|
|
21
10
|
export declare function decidirVisibilidad(h: {
|
|
22
11
|
respuesta: {
|
|
23
12
|
ok: boolean;
|
|
24
13
|
} | null;
|
|
25
14
|
huboError: boolean;
|
|
26
15
|
}): Visibilidad;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* el botón", no como "está pensando". Mostramos un indicador mientras el pedido está en vuelo
|
|
39
|
-
* ("submitted") y mientras ya empezó a transmitir pero todavía no llegó texto del asistente
|
|
40
|
-
* ("streaming" sin parts de texto no vacíos en el último mensaje). */
|
|
41
|
-
export declare function mostrarIndicadorDeEscritura(h: {
|
|
42
|
-
status: EstadoDelChat;
|
|
43
|
-
ultimoMensaje: MensajeMinimo | undefined;
|
|
44
|
-
}): boolean;
|
|
45
|
-
export {};
|
|
16
|
+
/** §2.5 del diseño: lo que el widget le cuenta al desarrollador. `decidirVisibilidad` sigue
|
|
17
|
+
* decidiendo si se dibuja; esto sólo agrega el porqué. `motivo` viene del motor vía
|
|
18
|
+
* `/api/chat/estado`; un backend viejo no lo manda y acá queda `null` — nunca se adivina. */
|
|
19
|
+
export declare function diagnosticoDesdeRespuesta(h: {
|
|
20
|
+
status: number;
|
|
21
|
+
cuerpo: {
|
|
22
|
+
ok?: boolean;
|
|
23
|
+
motivo?: string | null;
|
|
24
|
+
} | null;
|
|
25
|
+
huboError: boolean;
|
|
26
|
+
}): Diagnostico;
|
|
46
27
|
//# sourceMappingURL=estado-del-widget.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estado-del-widget.d.ts","sourceRoot":"","sources":["../src/estado-del-widget.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C
|
|
1
|
+
{"version":3,"file":"estado-del-widget.d.ts","sourceRoot":"","sources":["../src/estado-del-widget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C;;oEAEoE;AACpE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;2CAE2C;AAC3C,wBAAgB,kBAAkB,CAAC,CAAC,EAAE;IAAE,SAAS,EAAE;QAAE,EAAE,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,CAG5G;AAED;;6FAE6F;AAC7F,wBAAgB,yBAAyB,CAAC,CAAC,EAAE;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QAAE,EAAE,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,WAAW,CAId"}
|
package/dist/estado.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { CursorDeSesion, EventoDelWidget, OpcionDePregunta } from "./protocolo";
|
|
2
|
+
export interface Mensaje {
|
|
3
|
+
clave: number;
|
|
4
|
+
rol: "usuario" | "asistente";
|
|
5
|
+
texto: string;
|
|
6
|
+
/** asistente: todavía llegan deltas. usuario: mandado y todavía no confirmado por `usuario`. */
|
|
7
|
+
abierto: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface PreguntaPendiente {
|
|
10
|
+
requestId: string;
|
|
11
|
+
opciones: OpcionDePregunta[];
|
|
12
|
+
libre: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface ErrorVisible {
|
|
15
|
+
codigo: string;
|
|
16
|
+
mensaje: string;
|
|
17
|
+
terminal: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface EstadoDelChat {
|
|
20
|
+
mensajes: Mensaje[];
|
|
21
|
+
pregunta: PreguntaPendiente | null;
|
|
22
|
+
ocupado: boolean;
|
|
23
|
+
error: ErrorVisible | null;
|
|
24
|
+
/** `null` = el próximo mensaje abre una sesión nueva. */
|
|
25
|
+
cursor: CursorDeSesion | null;
|
|
26
|
+
siguienteClave: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function estadoInicial(cursor: CursorDeSesion | null): EstadoDelChat;
|
|
29
|
+
/** Optimista: lo que el usuario escribió se ve ya, y `usuario` lo confirma después (§2.4: nunca
|
|
30
|
+
* se pierde lo escrito). */
|
|
31
|
+
export declare function alEnviar(e: EstadoDelChat, texto: string): EstadoDelChat;
|
|
32
|
+
export declare function alResponder(e: EstadoDelChat): EstadoDelChat;
|
|
33
|
+
export declare function alReintentar(e: EstadoDelChat): EstadoDelChat;
|
|
34
|
+
/** El cuerpo HTTP terminó, con borde o sin él: nada más va a llegar por este stream. */
|
|
35
|
+
export declare function alTerminarStream(e: EstadoDelChat): EstadoDelChat;
|
|
36
|
+
export declare function reducir(e: EstadoDelChat, ev: EventoDelWidget): EstadoDelChat;
|
|
37
|
+
/** Entre Enviar y el primer token pasan 4-8 s en el peor caso (medido en la 1.x): sin indicador
|
|
38
|
+
* se lee como "se rompió el botón". Se apaga con el primer texto del asistente. */
|
|
39
|
+
export declare function mostrarIndicador(e: EstadoDelChat): boolean;
|
|
40
|
+
//# sourceMappingURL=estado.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estado.d.ts","sourceRoot":"","sources":["../src/estado.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMrF,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,SAAS,GAAG,WAAW,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,yDAAyD;IACzD,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,aAAa,CAE1E;AA0BD;4BAC4B;AAC5B,wBAAgB,QAAQ,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAEvE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,aAAa,CAE3D;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,GAAG,aAAa,CAE5D;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,aAAa,CAEhE;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,eAAe,GAAG,aAAa,CAsC5E;AAED;mFACmF;AACnF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,OAAO,CAI1D"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ImagenLista } from "./captura";
|
|
2
|
+
import type { ElementoSeleccionado } from "./elemento";
|
|
3
|
+
/** El motor cuenta 5 evidencias por sesión, de cualquier tipo, y el `contexto` que reenvía `abrir`
|
|
4
|
+
* ocupa una (Revisión 2 punto 4). Cuatro acá, antes que un quinto que siempre rebota con 429. */
|
|
5
|
+
export declare const MAX_ADJUNTOS = 4;
|
|
6
|
+
export type EstadoDeSubida = "pendiente" | "subiendo" | "listo" | "fallo";
|
|
7
|
+
interface AdjuntoBase {
|
|
8
|
+
clave: number;
|
|
9
|
+
estado: EstadoDeSubida;
|
|
10
|
+
evidenciaId: string | null;
|
|
11
|
+
motivo: string | null;
|
|
12
|
+
/** Con `fallo`: si vale la pena ofrecer «reintentar» (red, motor caído) o no (tope, rechazo). */
|
|
13
|
+
reintentable: boolean;
|
|
14
|
+
}
|
|
15
|
+
export type Adjunto = (AdjuntoBase & {
|
|
16
|
+
tipo: "elemento";
|
|
17
|
+
elemento: ElementoSeleccionado;
|
|
18
|
+
etiqueta: string;
|
|
19
|
+
}) | (AdjuntoBase & {
|
|
20
|
+
tipo: "captura";
|
|
21
|
+
imagen: ImagenLista;
|
|
22
|
+
});
|
|
23
|
+
export interface EstadoDeAdjuntos {
|
|
24
|
+
adjuntos: Adjunto[];
|
|
25
|
+
siguienteClave: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function sinAdjuntos(): EstadoDeAdjuntos;
|
|
28
|
+
export declare function puedeAgregar(e: EstadoDeAdjuntos): boolean;
|
|
29
|
+
/** «button «Guardar»»: lo que el chip muestra. El nombre accesible antes que el texto, y corto. */
|
|
30
|
+
export declare function etiquetaDelElemento(el: ElementoSeleccionado): string;
|
|
31
|
+
export declare function agregarElemento(e: EstadoDeAdjuntos, elemento: ElementoSeleccionado): EstadoDeAdjuntos;
|
|
32
|
+
export declare function agregarCaptura(e: EstadoDeAdjuntos, imagen: ImagenLista): EstadoDeAdjuntos;
|
|
33
|
+
export declare function quitar(e: EstadoDeAdjuntos, clave: number): EstadoDeAdjuntos;
|
|
34
|
+
export declare function marcar(e: EstadoDeAdjuntos, clave: number, cambio: {
|
|
35
|
+
estado: EstadoDeSubida;
|
|
36
|
+
evidenciaId?: string;
|
|
37
|
+
motivo?: string;
|
|
38
|
+
reintentable?: boolean;
|
|
39
|
+
}): EstadoDeAdjuntos;
|
|
40
|
+
export declare function pendientes(e: EstadoDeAdjuntos): Adjunto[];
|
|
41
|
+
export declare function ultimoElemento(e: EstadoDeAdjuntos): Extract<Adjunto, {
|
|
42
|
+
tipo: "elemento";
|
|
43
|
+
}> | null;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=adjuntos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adjuntos.d.ts","sourceRoot":"","sources":["../../src/evidencia/adjuntos.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAOvD;iGACiG;AACjG,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1E,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iGAAiG;IACjG,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,OAAO,GACf,CAAC,WAAW,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,oBAAoB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GACtF,CAAC,WAAW,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,WAAW,IAAI,gBAAgB,CAE9C;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAEzD;AAcD,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,oBAAoB,GAAG,MAAM,CAIpE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,oBAAoB,GAAG,gBAAgB,CAErG;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,GAAG,gBAAgB,CAEzF;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAG3E;AAED,wBAAgB,MAAM,CACpB,CAAC,EAAE,gBAAgB,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAChG,gBAAgB,CAelB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,EAAE,CAEzD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,GAAG,IAAI,CAMjG"}
|