rowsky-chatbot-widget 1.0.5

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.
@@ -0,0 +1,244 @@
1
+ const createWidgetAPI = (baseUrl) => {
2
+ const request = async (method, path, body = null, token = null) => {
3
+ const headers = { "Content-Type": "application/json" };
4
+ if (token) headers["Authorization"] = `Bearer ${token}`;
5
+ const options = { method, headers };
6
+ if (body) options.body = JSON.stringify(body);
7
+ const response = await fetch(`${baseUrl}${path}`, options);
8
+ if (!response.ok) {
9
+ const errorData = await response.json().catch(() => ({}));
10
+ const err = new Error(errorData.error || `HTTP ${response.status}`);
11
+ err.status = response.status;
12
+ err.data = errorData;
13
+ throw err;
14
+ }
15
+ return response.json();
16
+ };
17
+ return {
18
+ /**
19
+ * POST /widget/bootstrap
20
+ */
21
+ bootstrap: ({ clientId, visitorId }) => request("POST", "/widget/bootstrap", { clientId, visitorId }),
22
+ /**
23
+ * POST /widget/handshake
24
+ */
25
+ handshake: ({ botId, publicKey, visitorId }) => request("POST", "/widget/handshake", { botId, publicKey, visitorId }),
26
+ /**
27
+ * GET /widget/config
28
+ */
29
+ getConfig: (token) => request("GET", "/widget/config", null, token),
30
+ /**
31
+ * POST /widget/message
32
+ */
33
+ sendMessage: (token, message) => request("POST", "/widget/message", { message }, token),
34
+ /**
35
+ * POST /widget/lead
36
+ */
37
+ captureLead: (token, leadData) => request("POST", "/widget/lead", leadData, token)
38
+ };
39
+ };
40
+ const renderWidget = ({ config, token, api, visitorId, botId }) => {
41
+ const theme = config.theme || {};
42
+ const primaryColor = theme.primaryColor || "#dc2626";
43
+ const position = theme.position || "right";
44
+ const botName = config.botName || config.name || "Assistente";
45
+ const container = document.createElement("div");
46
+ container.id = "fluxia-widget-root";
47
+ container.className = "chatbot-scope fluxia-widget";
48
+ container.dataset.position = position;
49
+ container.style.setProperty("--fluxia-primary", primaryColor);
50
+ container.innerHTML = getWidgetHTML({
51
+ botName,
52
+ initialMessage: config.initialMessage
53
+ });
54
+ document.body.appendChild(container);
55
+ let isOpen = false;
56
+ const bubble = container.querySelector("#fluxia-bubble");
57
+ const chatBox = container.querySelector("#fluxia-chatbox");
58
+ const closeBtn = container.querySelector("#fluxia-close");
59
+ const input = container.querySelector("#fluxia-input");
60
+ const sendBtn = container.querySelector("#fluxia-send");
61
+ const messagesContainer = container.querySelector("#fluxia-messages");
62
+ if (config.initialMessage) {
63
+ addMessage("assistant", config.initialMessage);
64
+ }
65
+ bubble.addEventListener("click", () => toggle(true));
66
+ closeBtn.addEventListener("click", () => toggle(false));
67
+ sendBtn.addEventListener("click", handleSend);
68
+ input.addEventListener("keydown", (e) => {
69
+ if (e.key === "Enter" && !e.shiftKey) {
70
+ e.preventDefault();
71
+ handleSend();
72
+ }
73
+ });
74
+ function toggle(open) {
75
+ isOpen = open;
76
+ chatBox.style.display = isOpen ? "flex" : "none";
77
+ bubble.style.display = isOpen ? "none" : "flex";
78
+ }
79
+ function addMessage(role, content) {
80
+ const div = document.createElement("div");
81
+ div.className = `fluxia-msg fluxia-msg-${role}`;
82
+ div.textContent = content;
83
+ messagesContainer.appendChild(div);
84
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
85
+ }
86
+ async function handleSend() {
87
+ const text = input.value.trim();
88
+ if (!text) return;
89
+ input.value = "";
90
+ input.disabled = true;
91
+ sendBtn.disabled = true;
92
+ addMessage("user", text);
93
+ try {
94
+ const result = await api.sendMessage(token, text);
95
+ if (result.reply) {
96
+ addMessage("assistant", result.reply.content);
97
+ }
98
+ } catch (err) {
99
+ if (err.status === 401) {
100
+ addMessage("system", "Sessão expirada. Recarregue a página.");
101
+ } else {
102
+ addMessage("system", "Erro ao enviar mensagem. Tente novamente.");
103
+ }
104
+ console.error("[Fluxia]", err);
105
+ } finally {
106
+ input.disabled = false;
107
+ sendBtn.disabled = false;
108
+ input.focus();
109
+ }
110
+ }
111
+ };
112
+ function getWidgetHTML({ botName }) {
113
+ return `
114
+ <div id="fluxia-bubble" class="fluxia-bubble" aria-label="Abrir chat" role="button">
115
+ 💬
116
+ </div>
117
+
118
+ <div id="fluxia-chatbox" class="fluxia-chatbox" role="dialog" aria-live="polite">
119
+ <div class="fluxia-header">
120
+ <div class="fluxia-header-info">
121
+ <div class="fluxia-avatar">🤖</div>
122
+ <div>
123
+ <div class="fluxia-title">${botName}</div>
124
+ <div class="fluxia-status">Online</div>
125
+ </div>
126
+ </div>
127
+ <button id="fluxia-close" class="fluxia-close" aria-label="Fechar">✕</button>
128
+ </div>
129
+
130
+ <div id="fluxia-messages" class="fluxia-messages"></div>
131
+
132
+ <div class="fluxia-input-area">
133
+ <input id="fluxia-input" class="fluxia-input" type="text" placeholder="Digite sua mensagem..." />
134
+ <button id="fluxia-send" class="fluxia-send">Enviar</button>
135
+ </div>
136
+ </div>
137
+ `;
138
+ }
139
+ const cssText = '/* Estilos do widget Fluxia — injetados inline no bundle */\r\n\r\n.fluxia-widget {\r\n --fluxia-primary: #dc2626;\r\n --fluxia-radius: 16px;\r\n --fluxia-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);\r\n --fluxia-text: #0f172a;\r\n --fluxia-muted: #64748b;\r\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;\r\n}\r\n\r\n.fluxia-widget * {\r\n box-sizing: border-box;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\n.fluxia-bubble {\r\n position: fixed;\r\n bottom: 20px;\r\n z-index: 99999;\r\n width: 56px;\r\n height: 56px;\r\n border-radius: 50%;\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);\r\n font-size: 24px;\r\n transition: transform 0.2s;\r\n}\r\n\r\n.fluxia-bubble:hover {\r\n transform: scale(1.1);\r\n}\r\n\r\n.fluxia-chatbox {\r\n display: none;\r\n position: fixed;\r\n bottom: 90px;\r\n z-index: 99999;\r\n width: 370px;\r\n height: 520px;\r\n border-radius: var(--fluxia-radius);\r\n background: #fff;\r\n box-shadow: var(--fluxia-shadow);\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n.fluxia-widget[data-position="left"] .fluxia-bubble,\r\n.fluxia-widget[data-position="left"] .fluxia-chatbox {\r\n left: 20px;\r\n right: auto;\r\n}\r\n\r\n.fluxia-widget[data-position="right"] .fluxia-bubble,\r\n.fluxia-widget[data-position="right"] .fluxia-chatbox {\r\n right: 20px;\r\n left: auto;\r\n}\r\n\r\n.fluxia-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 14px 16px;\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n}\r\n\r\n.fluxia-header-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.fluxia-avatar {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 16px;\r\n}\r\n\r\n.fluxia-title {\r\n font-weight: 600;\r\n font-size: 14px;\r\n}\r\n\r\n.fluxia-status {\r\n font-size: 11px;\r\n opacity: 0.8;\r\n}\r\n\r\n.fluxia-close {\r\n background: none;\r\n border: none;\r\n color: #fff;\r\n font-size: 20px;\r\n cursor: pointer;\r\n padding: 4px;\r\n}\r\n\r\n.fluxia-messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n.fluxia-input-area {\r\n padding: 12px;\r\n border-top: 1px solid #e5e7eb;\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.fluxia-input {\r\n flex: 1;\r\n border: 1px solid #d1d5db;\r\n border-radius: 8px;\r\n padding: 8px 12px;\r\n font-size: 13px;\r\n outline: none;\r\n}\r\n\r\n.fluxia-send {\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n border: none;\r\n border-radius: 8px;\r\n padding: 8px 14px;\r\n cursor: pointer;\r\n font-size: 13px;\r\n font-weight: 600;\r\n}\r\n\r\n.fluxia-msg {\r\n max-width: 80%;\r\n padding: 10px 14px;\r\n border-radius: 12px;\r\n font-size: 13px;\r\n line-height: 1.5;\r\n word-wrap: break-word;\r\n}\r\n\r\n.fluxia-msg-user {\r\n align-self: flex-end;\r\n background: #f1f5f9;\r\n color: #1e293b;\r\n border-bottom-right-radius: 4px;\r\n}\r\n\r\n.fluxia-msg-assistant {\r\n align-self: flex-start;\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n border-bottom-left-radius: 4px;\r\n}\r\n\r\n.fluxia-msg-system {\r\n align-self: center;\r\n background: #fef3c7;\r\n color: #92400e;\r\n font-size: 12px;\r\n border-radius: 8px;\r\n text-align: center;\r\n}\r\n';
140
+ const VISITOR_ID_KEY = "fluxia_visitor_id";
141
+ const STYLE_TAG_ID = "fluxia-widget-styles";
142
+ const injectStyles = () => {
143
+ if (document.getElementById(STYLE_TAG_ID)) return;
144
+ if (!cssText.trim()) {
145
+ console.warn("[Fluxia] CSS nao carregado. Verifique o build.");
146
+ return;
147
+ }
148
+ const style = document.createElement("style");
149
+ style.id = STYLE_TAG_ID;
150
+ style.textContent = cssText;
151
+ document.head.appendChild(style);
152
+ };
153
+ const getVisitorId = () => {
154
+ let id = null;
155
+ try {
156
+ id = localStorage.getItem(VISITOR_ID_KEY);
157
+ } catch {
158
+ }
159
+ if (!id) {
160
+ id = "v_" + crypto.randomUUID();
161
+ try {
162
+ localStorage.setItem(VISITOR_ID_KEY, id);
163
+ } catch {
164
+ }
165
+ }
166
+ return id;
167
+ };
168
+ const getScriptConfig = () => {
169
+ const script = document.currentScript || document.querySelector("script[data-bot-id]");
170
+ if (!script) {
171
+ console.error(
172
+ "[Fluxia] Script tag não encontrada. Use data-bot-id e data-public-key."
173
+ );
174
+ return null;
175
+ }
176
+ const botId = script.getAttribute("data-bot-id");
177
+ const publicKey = script.getAttribute("data-public-key");
178
+ const clientId = script.getAttribute("data-client-id");
179
+ const apiBase = script.getAttribute("data-api-base") || "";
180
+ if (!apiBase || !clientId && (!botId || !publicKey)) {
181
+ console.error(
182
+ "[Fluxia] Atributos obrigatorios: data-api-base e (data-client-id OU data-bot-id + data-public-key)"
183
+ );
184
+ return null;
185
+ }
186
+ return {
187
+ botId: botId ? Number(botId) : null,
188
+ publicKey: publicKey || "",
189
+ clientId: clientId || "",
190
+ apiBase: apiBase.replace(/\/$/, "")
191
+ };
192
+ };
193
+ const init = async () => {
194
+ const config = getScriptConfig();
195
+ if (!config) return;
196
+ injectStyles();
197
+ const visitorId = getVisitorId();
198
+ const api = createWidgetAPI(config.apiBase);
199
+ try {
200
+ let token = "";
201
+ let botConfig = null;
202
+ if (config.clientId) {
203
+ const bootstrapResult = await api.bootstrap({
204
+ clientId: config.clientId,
205
+ visitorId
206
+ });
207
+ if (!bootstrapResult || !bootstrapResult.token) {
208
+ console.error("[Fluxia] Bootstrap falhou. Widget nao sera renderizado.");
209
+ return;
210
+ }
211
+ token = bootstrapResult.token;
212
+ botConfig = bootstrapResult.config || null;
213
+ } else {
214
+ const handshakeResult = await api.handshake({
215
+ botId: config.botId,
216
+ publicKey: config.publicKey,
217
+ visitorId
218
+ });
219
+ if (!handshakeResult || !handshakeResult.token) {
220
+ console.error("[Fluxia] Handshake falhou. Widget nao sera renderizado.");
221
+ return;
222
+ }
223
+ token = handshakeResult.token;
224
+ }
225
+ if (!botConfig) {
226
+ botConfig = await api.getConfig(token);
227
+ }
228
+ renderWidget({
229
+ config: botConfig,
230
+ token,
231
+ api,
232
+ visitorId,
233
+ botId: config.botId || (botConfig == null ? void 0 : botConfig.botId)
234
+ });
235
+ console.log("[Fluxia] Widget inicializado com sucesso.");
236
+ } catch (err) {
237
+ console.error("[Fluxia] Erro na inicialização:", err.message || err);
238
+ }
239
+ };
240
+ if (document.readyState === "loading") {
241
+ document.addEventListener("DOMContentLoaded", init);
242
+ } else {
243
+ init();
244
+ }
@@ -0,0 +1 @@
1
+ !function(n){"function"==typeof define&&define.amd?define(n):n()}(function(){"use strict";const n='/* Estilos do widget Fluxia — injetados inline no bundle */\r\n\r\n.fluxia-widget {\r\n --fluxia-primary: #dc2626;\r\n --fluxia-radius: 16px;\r\n --fluxia-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);\r\n --fluxia-text: #0f172a;\r\n --fluxia-muted: #64748b;\r\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;\r\n}\r\n\r\n.fluxia-widget * {\r\n box-sizing: border-box;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\n.fluxia-bubble {\r\n position: fixed;\r\n bottom: 20px;\r\n z-index: 99999;\r\n width: 56px;\r\n height: 56px;\r\n border-radius: 50%;\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);\r\n font-size: 24px;\r\n transition: transform 0.2s;\r\n}\r\n\r\n.fluxia-bubble:hover {\r\n transform: scale(1.1);\r\n}\r\n\r\n.fluxia-chatbox {\r\n display: none;\r\n position: fixed;\r\n bottom: 90px;\r\n z-index: 99999;\r\n width: 370px;\r\n height: 520px;\r\n border-radius: var(--fluxia-radius);\r\n background: #fff;\r\n box-shadow: var(--fluxia-shadow);\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n.fluxia-widget[data-position="left"] .fluxia-bubble,\r\n.fluxia-widget[data-position="left"] .fluxia-chatbox {\r\n left: 20px;\r\n right: auto;\r\n}\r\n\r\n.fluxia-widget[data-position="right"] .fluxia-bubble,\r\n.fluxia-widget[data-position="right"] .fluxia-chatbox {\r\n right: 20px;\r\n left: auto;\r\n}\r\n\r\n.fluxia-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 14px 16px;\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n}\r\n\r\n.fluxia-header-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.fluxia-avatar {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 16px;\r\n}\r\n\r\n.fluxia-title {\r\n font-weight: 600;\r\n font-size: 14px;\r\n}\r\n\r\n.fluxia-status {\r\n font-size: 11px;\r\n opacity: 0.8;\r\n}\r\n\r\n.fluxia-close {\r\n background: none;\r\n border: none;\r\n color: #fff;\r\n font-size: 20px;\r\n cursor: pointer;\r\n padding: 4px;\r\n}\r\n\r\n.fluxia-messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n.fluxia-input-area {\r\n padding: 12px;\r\n border-top: 1px solid #e5e7eb;\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.fluxia-input {\r\n flex: 1;\r\n border: 1px solid #d1d5db;\r\n border-radius: 8px;\r\n padding: 8px 12px;\r\n font-size: 13px;\r\n outline: none;\r\n}\r\n\r\n.fluxia-send {\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n border: none;\r\n border-radius: 8px;\r\n padding: 8px 14px;\r\n cursor: pointer;\r\n font-size: 13px;\r\n font-weight: 600;\r\n}\r\n\r\n.fluxia-msg {\r\n max-width: 80%;\r\n padding: 10px 14px;\r\n border-radius: 12px;\r\n font-size: 13px;\r\n line-height: 1.5;\r\n word-wrap: break-word;\r\n}\r\n\r\n.fluxia-msg-user {\r\n align-self: flex-end;\r\n background: #f1f5f9;\r\n color: #1e293b;\r\n border-bottom-right-radius: 4px;\r\n}\r\n\r\n.fluxia-msg-assistant {\r\n align-self: flex-start;\r\n background: var(--fluxia-primary);\r\n color: #fff;\r\n border-bottom-left-radius: 4px;\r\n}\r\n\r\n.fluxia-msg-system {\r\n align-self: center;\r\n background: #fef3c7;\r\n color: #92400e;\r\n font-size: 12px;\r\n border-radius: 8px;\r\n text-align: center;\r\n}\r\n',r="fluxia_visitor_id",e="fluxia-widget-styles",i=async()=>{const i=(()=>{const n=document.currentScript||document.querySelector("script[data-bot-id]");if(!n)return console.error("[Fluxia] Script tag não encontrada. Use data-bot-id e data-public-key."),null;const r=n.getAttribute("data-bot-id"),e=n.getAttribute("data-public-key"),i=n.getAttribute("data-client-id"),t=n.getAttribute("data-api-base")||"";return t&&(i||r&&e)?{botId:r?Number(r):null,publicKey:e||"",clientId:i||"",apiBase:t.replace(/\/$/,"")}:(console.error("[Fluxia] Atributos obrigatorios: data-api-base e (data-client-id OU data-bot-id + data-public-key)"),null)})();if(!i)return;(()=>{if(document.getElementById(e))return;if(!n.trim())return void console.warn("[Fluxia] CSS nao carregado. Verifique o build.");const r=document.createElement("style");r.id=e,r.textContent=n,document.head.appendChild(r)})();const t=(()=>{let n=null;try{n=localStorage.getItem(r)}catch{}if(!n){n="v_"+crypto.randomUUID();try{localStorage.setItem(r,n)}catch{}}return n})(),a=(n=>{const r=async(r,e,i=null,t=null)=>{const a={"Content-Type":"application/json"};t&&(a.Authorization=`Bearer ${t}`);const o={method:r,headers:a};i&&(o.body=JSON.stringify(i));const l=await fetch(`${n}${e}`,o);if(!l.ok){const n=await l.json().catch(()=>({})),r=new Error(n.error||`HTTP ${l.status}`);throw r.status=l.status,r.data=n,r}return l.json()};return{bootstrap:({clientId:n,visitorId:e})=>r("POST","/widget/bootstrap",{clientId:n,visitorId:e}),handshake:({botId:n,publicKey:e,visitorId:i})=>r("POST","/widget/handshake",{botId:n,publicKey:e,visitorId:i}),getConfig:n=>r("GET","/widget/config",null,n),sendMessage:(n,e)=>r("POST","/widget/message",{message:e},n),captureLead:(n,e)=>r("POST","/widget/lead",e,n)}})(i.apiBase);try{let n="",r=null;if(i.clientId){const e=await a.bootstrap({clientId:i.clientId,visitorId:t});if(!e||!e.token)return void console.error("[Fluxia] Bootstrap falhou. Widget nao sera renderizado.");n=e.token,r=e.config||null}else{const r=await a.handshake({botId:i.botId,publicKey:i.publicKey,visitorId:t});if(!r||!r.token)return void console.error("[Fluxia] Handshake falhou. Widget nao sera renderizado.");n=r.token}r||(r=await a.getConfig(n)),(({config:n,token:r,api:e,visitorId:i,botId:t})=>{const a=n.theme||{},o=a.primaryColor||"#dc2626",l=a.position||"right",s=n.botName||n.name||"Assistente",d=document.createElement("div");d.id="fluxia-widget-root",d.className="chatbot-scope fluxia-widget",d.dataset.position=l,d.style.setProperty("--fluxia-primary",o),d.innerHTML=function({botName:n}){return`\n <div id="fluxia-bubble" class="fluxia-bubble" aria-label="Abrir chat" role="button">\n 💬\n </div>\n\n <div id="fluxia-chatbox" class="fluxia-chatbox" role="dialog" aria-live="polite">\n <div class="fluxia-header">\n <div class="fluxia-header-info">\n <div class="fluxia-avatar">🤖</div>\n <div>\n <div class="fluxia-title">${n}</div>\n <div class="fluxia-status">Online</div>\n </div>\n </div>\n <button id="fluxia-close" class="fluxia-close" aria-label="Fechar">✕</button>\n </div>\n\n <div id="fluxia-messages" class="fluxia-messages"></div>\n\n <div class="fluxia-input-area">\n <input id="fluxia-input" class="fluxia-input" type="text" placeholder="Digite sua mensagem..." />\n <button id="fluxia-send" class="fluxia-send">Enviar</button>\n </div>\n </div>\n `}({botName:s,initialMessage:n.initialMessage}),document.body.appendChild(d);let u=!1;const c=d.querySelector("#fluxia-bubble"),f=d.querySelector("#fluxia-chatbox"),x=d.querySelector("#fluxia-close"),p=d.querySelector("#fluxia-input"),b=d.querySelector("#fluxia-send"),g=d.querySelector("#fluxia-messages");function m(n){u=n,f.style.display=u?"flex":"none",c.style.display=u?"none":"flex"}function y(n,r){const e=document.createElement("div");e.className=`fluxia-msg fluxia-msg-${n}`,e.textContent=r,g.appendChild(e),g.scrollTop=g.scrollHeight}async function h(){const n=p.value.trim();if(n){p.value="",p.disabled=!0,b.disabled=!0,y("user",n);try{const i=await e.sendMessage(r,n);i.reply&&y("assistant",i.reply.content)}catch(i){401===i.status?y("system","Sessão expirada. Recarregue a página."):y("system","Erro ao enviar mensagem. Tente novamente."),console.error("[Fluxia]",i)}finally{p.disabled=!1,b.disabled=!1,p.focus()}}}n.initialMessage&&y("assistant",n.initialMessage),c.addEventListener("click",()=>m(!0)),x.addEventListener("click",()=>m(!1)),b.addEventListener("click",h),p.addEventListener("keydown",n=>{"Enter"!==n.key||n.shiftKey||(n.preventDefault(),h())})})({config:r,token:n,api:a,visitorId:t,botId:i.botId||(null==r?void 0:r.botId)}),console.log("[Fluxia] Widget inicializado com sucesso.")}catch(o){console.error("[Fluxia] Erro na inicialização:",o.message||o)}};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",i):i()});
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "rowsky-chatbot-widget",
3
+ "version": "1.0.5",
4
+ "description": "Widget público do chatbot Fluxia para embed via script tag",
5
+ "main": "dist/chatbot.umd.js",
6
+ "module": "dist/chatbot.es.js",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "dev": "vite",
12
+ "build": "vite build",
13
+ "preview": "vite preview"
14
+ },
15
+ "devDependencies": {
16
+ "terser": "^5.46.0",
17
+ "vite": "^6.2.0"
18
+ }
19
+ }