rio-assist-widget 0.1.28 → 0.1.32

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/src/main.ts CHANGED
@@ -13,21 +13,21 @@ export type RioAssistOptions = {
13
13
 
14
14
  const DEFAULT_OPTIONS: Required<Omit<RioAssistOptions, 'target'>> = {
15
15
  title: 'Rio Insight',
16
- buttonLabel: 'Rio Insight',
17
- placeholder: 'Pergunte alguma coisa',
18
- suggestions: [
19
- 'Resumo da Frota',
20
- 'Frota Disponível',
21
- 'Chamados Abertos',
22
- 'Parados + Causas',
23
- 'Aguardando Peças',
24
- 'Principais Gargalos',
25
- 'Tempo por Concessionária',
26
- 'Tempo de Ciclo',
27
- 'Preventiva x Corretiva',
28
- ],
29
- accentColor: '#008B9A',
30
- apiBaseUrl: '',
16
+ buttonLabel: 'Rio Insight',
17
+ placeholder: 'Pergunte alguma coisa',
18
+ suggestions: [
19
+ 'Resumo da Frota',
20
+ 'Frota Disponível',
21
+ 'Chamados Abertos',
22
+ 'Parados + Causas',
23
+ 'Aguardando Peças',
24
+ 'Principais Gargalos',
25
+ 'Tempo por Concessionária',
26
+ 'Tempo de Ciclo',
27
+ 'Preventiva x Corretiva',
28
+ ],
29
+ accentColor: '#008B9A',
30
+ apiBaseUrl: '',
31
31
  rioToken: '',
32
32
  };
33
33
 
package/src/playground.ts CHANGED
@@ -1,31 +1,31 @@
1
- import './main';
2
-
3
- const rioToken = import.meta.env.VITE_RIO_TOKEN || 'SEU_TOKEN_RIO_AQUI';
4
- const apiBaseUrl = import.meta.env.VITE_RIO_API_BASE_URL || '';
5
-
6
- const boot = () => {
7
- window.RioAssist?.init({
8
- title: 'Rio Insight',
9
- buttonLabel: 'Rio Insight',
10
- accentColor: '#c02267',
11
- rioToken,
12
- apiBaseUrl,
13
- suggestions: [
14
- 'Resumo da Frota',
15
- 'Frota Disponível',
16
- 'Chamados Abertos',
17
- 'Parados + Causas',
18
- 'Aguardando Peças',
19
- 'Principais Gargalos',
20
- 'Tempo por Concessionária',
21
- 'Tempo de Ciclo',
22
- 'Preventiva x Corretiva',
23
- ],
24
- });
25
- };
26
-
27
- if (window.RioAssist) {
28
- boot();
29
- } else {
30
- window.addEventListener('rio-assist-ready', boot, { once: true });
31
- }
1
+ import './main';
2
+
3
+ const rioToken = import.meta.env.VITE_RIO_TOKEN || 'SEU_TOKEN_RIO_AQUI';
4
+ const apiBaseUrl = import.meta.env.VITE_RIO_API_BASE_URL || '';
5
+
6
+ const boot = () => {
7
+ window.RioAssist?.init({
8
+ title: 'Rio Insight',
9
+ buttonLabel: 'Rio Insight',
10
+ accentColor: '#c02267',
11
+ rioToken,
12
+ apiBaseUrl,
13
+ suggestions: [
14
+ 'Resumo da Frota',
15
+ 'Frota Disponível',
16
+ 'Chamados Abertos',
17
+ 'Parados + Causas',
18
+ 'Aguardando Peças',
19
+ 'Principais Gargalos',
20
+ 'Tempo por Concessionária',
21
+ 'Tempo de Ciclo',
22
+ 'Preventiva x Corretiva',
23
+ ],
24
+ });
25
+ };
26
+
27
+ if (window.RioAssist) {
28
+ boot();
29
+ } else {
30
+ window.addEventListener('rio-assist-ready', boot, { once: true });
31
+ }
@@ -1,91 +1,91 @@
1
- const WEBSOCKET_URL = 'wss://ws.volkswagen.latam-sandbox.rio.cloud';
2
- const HEARTBEAT_INTERVAL_MS = 5 * 60_000; // keep-alive before the 10min idle timeout
1
+ const WEBSOCKET_URL = 'wss://ws.volkswagen.latam-sandbox.rio.cloud';
2
+ const HEARTBEAT_INTERVAL_MS = 5 * 60_000; // keep-alive before the 10min idle timeout
3
3
 
4
- export type RioIncomingMessage = {
5
- text: string;
6
- raw: string;
7
- data: unknown;
8
- action?: string;
9
- };
4
+ export type RioIncomingMessage = {
5
+ text: string;
6
+ raw: string;
7
+ data: unknown;
8
+ action?: string;
9
+ };
10
10
 
11
11
  export class RioWebsocketClient {
12
12
  readonly token: string;
13
13
 
14
14
  private socket: WebSocket | null = null;
15
15
 
16
- private connectPromise: Promise<void> | null = null;
17
-
18
- private readonly listeners = new Set<(message: RioIncomingMessage) => void>();
19
-
20
- private heartbeatId: number | null = null;
21
-
22
- constructor(token: string) {
23
- this.token = token;
24
- }
16
+ private connectPromise: Promise<void> | null = null;
17
+
18
+ private readonly listeners = new Set<(message: RioIncomingMessage) => void>();
19
+
20
+ private heartbeatId: number | null = null;
21
+
22
+ constructor(token: string) {
23
+ this.token = token;
24
+ }
25
25
 
26
26
  matchesToken(value: string) {
27
27
  return this.token === value;
28
28
  }
29
29
 
30
- async sendMessage(message: string, conversationId?: string | null) {
31
- const socket = await this.ensureConnection();
32
-
33
- const payload = {
34
- action: 'sendMessage',
35
- message,
36
- conversationId: conversationId ?? null,
37
- };
38
-
39
- console.info('[RioAssist][ws] enviando payload de mensagem', payload);
40
- socket.send(JSON.stringify(payload));
41
- }
42
-
43
- async requestHistory(options: { conversationId?: string | null; limit?: number } = {}) {
44
- const socket = await this.ensureConnection();
45
- const payload: Record<string, unknown> = {
46
- action: 'getHistory',
47
- limit: options.limit ?? 50,
48
- conversationId: options.conversationId ?? null,
49
- };
50
-
51
- socket.send(JSON.stringify(payload));
52
- }
53
-
54
- async renameConversation(conversationId: string, newTitle: string) {
55
- const socket = await this.ensureConnection();
56
- const payload = {
57
- action: 'renameConversation',
58
- conversationId,
59
- newTitle,
60
- };
61
-
62
- console.info('[RioAssist][ws] enviando renameConversation', payload);
63
- socket.send(JSON.stringify(payload));
64
- }
65
-
66
- async deleteConversation(conversationId: string) {
67
- const socket = await this.ensureConnection();
68
- const payload = {
69
- action: 'deleteConversation',
70
- conversationId,
71
- };
72
-
73
- console.info('[RioAssist][ws] enviando deleteConversation', payload);
74
- socket.send(JSON.stringify(payload));
75
- }
76
-
77
- onMessage(listener: (message: RioIncomingMessage) => void) {
78
- this.listeners.add(listener);
79
- return () => this.listeners.delete(listener);
80
- }
81
-
82
- close() {
83
- this.stopHeartbeat();
84
- if (this.socket && this.socket.readyState === WebSocket.OPEN) {
85
- this.socket.close();
86
- }
87
-
88
- this.connectPromise = null;
30
+ async sendMessage(message: string, conversationId?: string | null) {
31
+ const socket = await this.ensureConnection();
32
+
33
+ const payload = {
34
+ action: 'sendMessage',
35
+ message,
36
+ conversationId: conversationId ?? null,
37
+ };
38
+
39
+ console.info('[RioAssist][ws] enviando payload de mensagem', payload);
40
+ socket.send(JSON.stringify(payload));
41
+ }
42
+
43
+ async requestHistory(options: { conversationId?: string | null; limit?: number } = {}) {
44
+ const socket = await this.ensureConnection();
45
+ const payload: Record<string, unknown> = {
46
+ action: 'getHistory',
47
+ limit: options.limit ?? 50,
48
+ conversationId: options.conversationId ?? null,
49
+ };
50
+
51
+ socket.send(JSON.stringify(payload));
52
+ }
53
+
54
+ async renameConversation(conversationId: string, newTitle: string) {
55
+ const socket = await this.ensureConnection();
56
+ const payload = {
57
+ action: 'renameConversation',
58
+ conversationId,
59
+ newTitle,
60
+ };
61
+
62
+ console.info('[RioAssist][ws] enviando renameConversation', payload);
63
+ socket.send(JSON.stringify(payload));
64
+ }
65
+
66
+ async deleteConversation(conversationId: string) {
67
+ const socket = await this.ensureConnection();
68
+ const payload = {
69
+ action: 'deleteConversation',
70
+ conversationId,
71
+ };
72
+
73
+ console.info('[RioAssist][ws] enviando deleteConversation', payload);
74
+ socket.send(JSON.stringify(payload));
75
+ }
76
+
77
+ onMessage(listener: (message: RioIncomingMessage) => void) {
78
+ this.listeners.add(listener);
79
+ return () => this.listeners.delete(listener);
80
+ }
81
+
82
+ close() {
83
+ this.stopHeartbeat();
84
+ if (this.socket && this.socket.readyState === WebSocket.OPEN) {
85
+ this.socket.close();
86
+ }
87
+
88
+ this.connectPromise = null;
89
89
  this.socket = null;
90
90
  this.listeners.clear();
91
91
  }
@@ -104,32 +104,32 @@ export class RioWebsocketClient {
104
104
  `${WEBSOCKET_URL}?token=${encodeURIComponent(this.token)}`,
105
105
  );
106
106
 
107
- this.socket.addEventListener('message', (event) => this.handleMessage(event));
108
- this.socket.addEventListener('close', () => {
109
- this.connectPromise = null;
110
- this.socket = null;
111
- this.stopHeartbeat();
112
- });
107
+ this.socket.addEventListener('message', (event) => this.handleMessage(event));
108
+ this.socket.addEventListener('close', () => {
109
+ this.connectPromise = null;
110
+ this.socket = null;
111
+ this.stopHeartbeat();
112
+ });
113
113
 
114
114
  this.connectPromise = new Promise((resolve, reject) => {
115
115
  if (!this.socket) {
116
116
  reject(new Error('Falha ao criar conexão WebSocket.'));
117
117
  return;
118
118
  }
119
-
120
- const handleOpen = () => {
121
- cleanup();
122
- if (this.socket) {
123
- this.startHeartbeat(this.socket);
124
- }
125
- resolve();
126
- };
127
-
128
- const handleError = () => {
129
- cleanup();
130
- this.stopHeartbeat();
131
- this.socket?.close();
132
- this.socket = null;
119
+
120
+ const handleOpen = () => {
121
+ cleanup();
122
+ if (this.socket) {
123
+ this.startHeartbeat(this.socket);
124
+ }
125
+ resolve();
126
+ };
127
+
128
+ const handleError = () => {
129
+ cleanup();
130
+ this.stopHeartbeat();
131
+ this.socket?.close();
132
+ this.socket = null;
133
133
  this.connectPromise = null;
134
134
  reject(
135
135
  new Error(
@@ -153,57 +153,57 @@ export class RioWebsocketClient {
153
153
  throw new Error('Conexão WebSocket do Rio Insight não está pronta.');
154
154
  }
155
155
 
156
- return this.socket;
157
- }
158
-
159
- private startHeartbeat(socket: WebSocket) {
160
- this.stopHeartbeat();
161
- this.heartbeatId = window.setInterval(() => {
162
- if (socket.readyState === WebSocket.OPEN) {
163
- socket.send(JSON.stringify({ action: 'ping' }));
164
- }
165
- }, HEARTBEAT_INTERVAL_MS);
166
- }
167
-
168
- private stopHeartbeat() {
169
- if (this.heartbeatId !== null) {
170
- window.clearInterval(this.heartbeatId);
171
- this.heartbeatId = null;
172
- }
173
- }
174
-
175
- private async handleMessage(event: MessageEvent) {
176
- const raw = await this.readMessage(event.data);
177
- let parsed: unknown = null;
178
- let text = raw;
179
- let action: string | undefined;
180
-
181
- try {
182
- parsed = JSON.parse(raw);
183
- if (typeof parsed === 'object' && parsed !== null) {
184
- const maybeAction =
185
- (parsed as any).action ?? (parsed as any).type ?? (parsed as any).event;
186
-
187
- if (typeof maybeAction === 'string') {
188
- action = maybeAction;
189
- }
190
-
191
- const maybeText =
192
- (parsed as any).message ??
193
- (parsed as any).response ??
194
- (parsed as any).text ??
195
- (parsed as any).content;
156
+ return this.socket;
157
+ }
158
+
159
+ private startHeartbeat(socket: WebSocket) {
160
+ this.stopHeartbeat();
161
+ this.heartbeatId = window.setInterval(() => {
162
+ if (socket.readyState === WebSocket.OPEN) {
163
+ socket.send(JSON.stringify({ action: 'ping' }));
164
+ }
165
+ }, HEARTBEAT_INTERVAL_MS);
166
+ }
167
+
168
+ private stopHeartbeat() {
169
+ if (this.heartbeatId !== null) {
170
+ window.clearInterval(this.heartbeatId);
171
+ this.heartbeatId = null;
172
+ }
173
+ }
174
+
175
+ private async handleMessage(event: MessageEvent) {
176
+ const raw = await this.readMessage(event.data);
177
+ let parsed: unknown = null;
178
+ let text = raw;
179
+ let action: string | undefined;
180
+
181
+ try {
182
+ parsed = JSON.parse(raw);
183
+ if (typeof parsed === 'object' && parsed !== null) {
184
+ const maybeAction =
185
+ (parsed as any).action ?? (parsed as any).type ?? (parsed as any).event;
186
+
187
+ if (typeof maybeAction === 'string') {
188
+ action = maybeAction;
189
+ }
190
+
191
+ const maybeText =
192
+ (parsed as any).message ??
193
+ (parsed as any).response ??
194
+ (parsed as any).text ??
195
+ (parsed as any).content;
196
196
 
197
197
  if (typeof maybeText === 'string') {
198
198
  text = maybeText;
199
199
  }
200
200
  }
201
- } catch {
202
- parsed = null;
203
- }
204
-
205
- this.listeners.forEach((listener) => listener({ text, raw, data: parsed, action }));
206
- }
201
+ } catch {
202
+ parsed = null;
203
+ }
204
+
205
+ this.listeners.forEach((listener) => listener({ text, raw, data: parsed, action }));
206
+ }
207
207
 
208
208
  private async readMessage(
209
209
  data: MessageEvent['data'],