@spilki/widget 0.1.0 → 0.1.2
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/README.md +29 -25
- package/dist/bootstrap.es.js +168 -120
- package/dist/bootstrap.es.js.map +1 -1
- package/dist/bootstrap.umd.js +4 -4
- package/dist/bootstrap.umd.js.map +1 -1
- package/dist/core/jwt.d.ts.map +1 -1
- package/dist/core/state.d.ts +5 -2
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/transport.d.ts +1 -2
- package/dist/core/transport.d.ts.map +1 -1
- package/dist/core/utils.d.ts +4 -4
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/widget.es.js +169 -121
- package/dist/widget.es.js.map +1 -1
- package/dist/widget.umd.js +4 -4
- package/dist/widget.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/widget.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const O = `
|
|
2
2
|
<style>
|
|
3
3
|
:host {
|
|
4
4
|
all: initial;
|
|
@@ -44,11 +44,11 @@ const S = `
|
|
|
44
44
|
</span>
|
|
45
45
|
</button>
|
|
46
46
|
`;
|
|
47
|
-
function
|
|
47
|
+
function M(r) {
|
|
48
48
|
const e = document.createElement("div");
|
|
49
49
|
e.setAttribute("part", "bubble-root"), e.style.setProperty("--spilki-accent", r.color), e.style.position = "fixed", e.style.bottom = "24px", e.style[r.position === "bottom-right" ? "right" : "left"] = "24px";
|
|
50
50
|
const t = e.attachShadow({ mode: "open" });
|
|
51
|
-
t.innerHTML =
|
|
51
|
+
t.innerHTML = O;
|
|
52
52
|
const s = t.querySelector("button");
|
|
53
53
|
return s.addEventListener("click", () => r.onClick()), {
|
|
54
54
|
element: e,
|
|
@@ -58,16 +58,16 @@ function I(r) {
|
|
|
58
58
|
destroy() {
|
|
59
59
|
e.remove();
|
|
60
60
|
},
|
|
61
|
-
setOpen(
|
|
62
|
-
s.setAttribute("aria-expanded", String(
|
|
61
|
+
setOpen(n) {
|
|
62
|
+
s.setAttribute("aria-expanded", String(n));
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
const
|
|
67
|
-
class
|
|
66
|
+
const A = ':host{--spilki-bg-light: #ffffff;--spilki-bg-dark: #0f172a;--spilki-text-light: #0f172a;--spilki-text-dark: #f8fafc;--spilki-border-light: rgba(15, 23, 42, .1);--spilki-border-dark: rgba(148, 163, 184, .25);--spilki-shadow: 0 10px 40px rgba(15, 23, 42, .2);--spilki-radius: 16px;--spilki-font: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;color:inherit;font-family:var(--spilki-font)}.wrapper{width:100%;height:100%;display:flex;flex-direction:column;background:var(--spilki-surface);color:var(--spilki-text);border-radius:var(--spilki-radius);box-shadow:var(--spilki-shadow);border:1px solid var(--spilki-border);overflow:hidden}header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--spilki-surface);border-bottom:1px solid var(--spilki-border)}header h1{font-size:1rem;margin:0;display:flex;align-items:center;gap:.5rem}header button.close{border:none;background:transparent;color:inherit;font-size:1.25rem;cursor:pointer}header .status-dot{width:10px;height:10px;border-radius:999px;background:var(--spilki-accent)}.messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.5rem}.message{display:flex;flex-direction:column;gap:.25rem;max-width:85%;line-height:1.4;word-wrap:break-word;overflow-wrap:anywhere;white-space:pre-wrap}.message.user{align-self:flex-end;text-align:right}.message .bubble{padding:.6rem .8rem;border-radius:1rem;background:#6366f126}.message.user .bubble{background:var(--spilki-accent);color:#fff}.message.bot .bubble{background:#94a3b826}.input-area{display:flex;align-items:flex-end;gap:.5rem;padding:.75rem 1rem;border-top:1px solid var(--spilki-border)}.input-area textarea{flex:1;resize:none;min-height:2.5rem;max-height:6rem;border-radius:.75rem;border:1px solid var(--spilki-border);padding:.6rem .75rem;font-family:inherit;font-size:.95rem;background:var(--spilki-surface);color:var(--spilki-text)}.input-area button{border:none;border-radius:999px;padding:.6rem 1.1rem;background:var(--spilki-accent);color:#fff;font-weight:600;cursor:pointer}.typing{font-size:.75rem;color:#94a3b8e6;padding:0 1rem .75rem}.offline{font-size:.8rem;padding:0 1rem;color:#f97316}:host([data-theme="dark"]){--spilki-surface: var(--spilki-bg-dark);--spilki-text: var(--spilki-text-dark);--spilki-border: var(--spilki-border-dark)}:host([data-theme="light"]){--spilki-surface: var(--spilki-bg-light);--spilki-text: var(--spilki-text-light);--spilki-border: var(--spilki-border-light)}:host([data-theme="dark"]) .message .bubble{background:#94a3b81f}:host([data-theme="dark"]) .message.bot .bubble{background:#6366f126}:host([data-theme="dark"]) .input-area textarea{background:#0f172ad9}.messages::-webkit-scrollbar,.input-area textarea::-webkit-scrollbar{width:6px}.messages::-webkit-scrollbar-track,.input-area textarea::-webkit-scrollbar-track{background:transparent}.messages::-webkit-scrollbar-thumb,.input-area textarea::-webkit-scrollbar-thumb{background:#94a3b84d;border-radius:999px}.messages::-webkit-scrollbar-thumb:hover,.input-area textarea::-webkit-scrollbar-thumb:hover{background:#94a3b880}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb{background:#fff3}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb:hover,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb:hover{background:#ffffff59}.messages{scroll-behavior:smooth}';
|
|
67
|
+
class C {
|
|
68
68
|
constructor(e) {
|
|
69
69
|
this.options = e, this.focusable = [], this.open = !1, this.host = document.createElement("div"), this.host.setAttribute("part", "panel-root"), this.host.style.position = "fixed", this.host.style.bottom = "96px", this.host.style[e.position === "bottom-right" ? "right" : "left"] = "24px", this.host.style.width = "360px", this.host.style.maxWidth = "calc(100vw - 32px)", this.host.style.height = "520px", this.host.style.display = "none", this.host.style.zIndex = "2147483001", this.shadow = this.host.attachShadow({ mode: "open" }), this.shadow.innerHTML = `
|
|
70
|
-
<style>${
|
|
70
|
+
<style>${A}</style>
|
|
71
71
|
<div class="wrapper" role="dialog" aria-modal="true" aria-label="${e.i18n.title}">
|
|
72
72
|
<header>
|
|
73
73
|
<h1><span class="status-dot" aria-hidden="true"></span>${e.i18n.title}</h1>
|
|
@@ -149,15 +149,15 @@ class O {
|
|
|
149
149
|
e.shiftKey && i === t ? (e.preventDefault(), s.focus()) : !e.shiftKey && i === s && (e.preventDefault(), t.focus());
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
-
const
|
|
152
|
+
const W = "https://api.spilki.ai", g = {
|
|
153
153
|
welcome: "Hi! I'm your assistant.",
|
|
154
154
|
placeholder: "Type a message…",
|
|
155
155
|
sendLabel: "Send",
|
|
156
156
|
typing: "Assistant is typing…",
|
|
157
157
|
offline: "Unable to connect. Please try again later.",
|
|
158
158
|
title: "Spilki Assistant"
|
|
159
|
-
},
|
|
160
|
-
apiBase:
|
|
159
|
+
}, p = {
|
|
160
|
+
apiBase: W,
|
|
161
161
|
position: "bottom-right",
|
|
162
162
|
theme: "auto",
|
|
163
163
|
color: "#6366f1",
|
|
@@ -165,43 +165,43 @@ const M = "https://api.spilki.ai", g = {
|
|
|
165
165
|
persist: !0,
|
|
166
166
|
i18n: g
|
|
167
167
|
};
|
|
168
|
-
function
|
|
169
|
-
var t, s, i,
|
|
168
|
+
function $(r) {
|
|
169
|
+
var t, s, i, n, l, a, h;
|
|
170
170
|
const e = { ...g, ...(t = r.i18n) != null ? t : {} };
|
|
171
171
|
return {
|
|
172
|
-
...
|
|
172
|
+
...p,
|
|
173
173
|
...r,
|
|
174
|
-
apiBase: (s = r.apiBase) != null ? s :
|
|
174
|
+
apiBase: (s = r.apiBase) != null ? s : p.apiBase,
|
|
175
175
|
i18n: e,
|
|
176
176
|
welcome: (i = r.welcome) != null ? i : e.welcome,
|
|
177
|
-
position: (
|
|
178
|
-
theme: (
|
|
179
|
-
color: (
|
|
180
|
-
persist: (
|
|
177
|
+
position: (n = r.position) != null ? n : p.position,
|
|
178
|
+
theme: (l = r.theme) != null ? l : p.theme,
|
|
179
|
+
color: (a = r.color) != null ? a : p.color,
|
|
180
|
+
persist: (h = r.persist) != null ? h : p.persist
|
|
181
181
|
};
|
|
182
182
|
}
|
|
183
|
-
function
|
|
183
|
+
function B(r = "msg") {
|
|
184
184
|
return typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${r}-${Math.random().toString(16).slice(2)}`;
|
|
185
185
|
}
|
|
186
|
-
function
|
|
186
|
+
function L() {
|
|
187
187
|
var r, e;
|
|
188
188
|
return (e = (r = window.matchMedia) == null ? void 0 : r.call(window, "(prefers-color-scheme: dark)").matches) != null ? e : !1;
|
|
189
189
|
}
|
|
190
|
-
function
|
|
191
|
-
return r === "light" || r === "dark" ? r :
|
|
190
|
+
function x(r) {
|
|
191
|
+
return r === "light" || r === "dark" ? r : L() ? "dark" : "light";
|
|
192
192
|
}
|
|
193
193
|
function u(r, e = 30) {
|
|
194
194
|
return r.slice(-e);
|
|
195
195
|
}
|
|
196
|
-
function
|
|
196
|
+
function K(r) {
|
|
197
197
|
if (!r || r.length === 0) return;
|
|
198
198
|
const e = window.location.origin;
|
|
199
199
|
r.includes(e) || console.warn(
|
|
200
200
|
`SpilkiWidget: current origin ${e} not in allowedOriginsHint: ${r.join(", ")}`
|
|
201
201
|
);
|
|
202
202
|
}
|
|
203
|
-
const d = 1500,
|
|
204
|
-
class
|
|
203
|
+
const d = 1500, v = 8e3;
|
|
204
|
+
class P {
|
|
205
205
|
constructor(e, t) {
|
|
206
206
|
this.sessionId = null, this.currentKind = null, this.stopped = !1, this.backoff = d, this.options = e, this.handlers = t;
|
|
207
207
|
}
|
|
@@ -213,11 +213,10 @@ class L {
|
|
|
213
213
|
return (t = (e = this.sessionId) != null ? e : this.options.sessionId) != null ? t : null;
|
|
214
214
|
}
|
|
215
215
|
async connect() {
|
|
216
|
-
var
|
|
216
|
+
var l, a;
|
|
217
217
|
this.stopped = !1;
|
|
218
|
-
const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/
|
|
218
|
+
const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/session`, t = (a = (l = this.sessionId) != null ? l : this.options.sessionId) != null ? a : void 0, s = {
|
|
219
219
|
organisationId: this.options.org,
|
|
220
|
-
assistantId: this.options.assistant,
|
|
221
220
|
sessionId: t,
|
|
222
221
|
userAgent: typeof navigator != "undefined" ? navigator.userAgent : "",
|
|
223
222
|
referrer: typeof document != "undefined" ? document.referrer : "",
|
|
@@ -226,19 +225,19 @@ class L {
|
|
|
226
225
|
method: "POST",
|
|
227
226
|
headers: {
|
|
228
227
|
"Content-Type": "application/json",
|
|
229
|
-
...this.options.
|
|
228
|
+
...this.options.accessToken ? { Authorization: `Bearer ${this.options.accessToken}` } : {}
|
|
230
229
|
},
|
|
231
230
|
body: JSON.stringify(s)
|
|
232
231
|
});
|
|
233
232
|
if (!i.ok)
|
|
234
233
|
throw new Error(`SpilkiWidget: connect failed (${i.status})`);
|
|
235
|
-
const
|
|
236
|
-
return this.sessionId =
|
|
234
|
+
const n = await i.json();
|
|
235
|
+
return this.sessionId = n.sessionId, this.options.sessionId = n.sessionId, this.backoff = d, await this.startTransport(n), n;
|
|
237
236
|
}
|
|
238
237
|
async send(e) {
|
|
239
|
-
var
|
|
238
|
+
var n, l;
|
|
240
239
|
const t = {
|
|
241
|
-
sessionId: (
|
|
240
|
+
sessionId: (l = (n = this.sessionId) != null ? n : this.options.sessionId) != null ? l : "",
|
|
242
241
|
text: e
|
|
243
242
|
};
|
|
244
243
|
if (!t.sessionId)
|
|
@@ -251,7 +250,7 @@ class L {
|
|
|
251
250
|
method: "POST",
|
|
252
251
|
headers: {
|
|
253
252
|
"Content-Type": "application/json",
|
|
254
|
-
...this.options.
|
|
253
|
+
...this.options.accessToken ? { Authorization: `Bearer ${this.options.accessToken}` } : {}
|
|
255
254
|
},
|
|
256
255
|
body: JSON.stringify(t)
|
|
257
256
|
});
|
|
@@ -284,7 +283,7 @@ class L {
|
|
|
284
283
|
return;
|
|
285
284
|
}
|
|
286
285
|
this.currentKind = "ws", this.handlers.onOpen("ws"), this.backoff = d, t();
|
|
287
|
-
}), i.addEventListener("message", (
|
|
286
|
+
}), i.addEventListener("message", (n) => this.handleIncoming(n.data)), i.addEventListener("close", () => {
|
|
288
287
|
this.stopped || this.retryFallback("ws");
|
|
289
288
|
}), i.addEventListener("error", () => {
|
|
290
289
|
this.handlers.onError(new Error("SpilkiWidget: websocket error")), i.readyState !== WebSocket.OPEN && s(new Error("WebSocket failed"));
|
|
@@ -302,15 +301,15 @@ class L {
|
|
|
302
301
|
}
|
|
303
302
|
const i = new EventSource(e);
|
|
304
303
|
this.sse = i;
|
|
305
|
-
let
|
|
304
|
+
let n = !1;
|
|
306
305
|
i.addEventListener("open", () => {
|
|
307
|
-
if (
|
|
306
|
+
if (n = !0, this.stopped) {
|
|
308
307
|
i.close();
|
|
309
308
|
return;
|
|
310
309
|
}
|
|
311
310
|
this.currentKind = "sse", this.handlers.onOpen("sse"), this.backoff = d, t();
|
|
312
|
-
}), i.addEventListener("message", (
|
|
313
|
-
if (!
|
|
311
|
+
}), i.addEventListener("message", (l) => this.handleIncoming(l.data)), i.addEventListener("error", () => {
|
|
312
|
+
if (!n) {
|
|
314
313
|
s(new Error("SSE failed"));
|
|
315
314
|
return;
|
|
316
315
|
}
|
|
@@ -326,9 +325,9 @@ class L {
|
|
|
326
325
|
const s = await fetch(e);
|
|
327
326
|
if (!s.ok) throw new Error(`Poll failed ${s.status}`);
|
|
328
327
|
const i = await s.json();
|
|
329
|
-
u(i).forEach((
|
|
328
|
+
u(i).forEach((n) => this.handlers.onMessage(n)), this.backoff = d;
|
|
330
329
|
} catch (s) {
|
|
331
|
-
this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5,
|
|
330
|
+
this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5, v);
|
|
332
331
|
} finally {
|
|
333
332
|
this.stopped || (this.pollTimer = window.setTimeout(t, this.backoff));
|
|
334
333
|
}
|
|
@@ -336,7 +335,7 @@ class L {
|
|
|
336
335
|
await t();
|
|
337
336
|
}
|
|
338
337
|
retryFallback(e) {
|
|
339
|
-
this.stopped || (this.stop(), this.backoff = Math.min(this.backoff * 1.5,
|
|
338
|
+
this.stopped || (this.stop(), this.backoff = Math.min(this.backoff * 1.5, v), setTimeout(() => {
|
|
340
339
|
this.handlers.onError(new Error(`SpilkiWidget: retrying after ${e}`)), this.connect().catch((t) => this.handlers.onError(t));
|
|
341
340
|
}, this.backoff));
|
|
342
341
|
}
|
|
@@ -368,14 +367,14 @@ class L {
|
|
|
368
367
|
}
|
|
369
368
|
}
|
|
370
369
|
const f = 30;
|
|
371
|
-
class
|
|
372
|
-
constructor(e, t
|
|
373
|
-
this.org = e, this.
|
|
370
|
+
class U {
|
|
371
|
+
constructor(e, t) {
|
|
372
|
+
this.org = e, this.listeners = /* @__PURE__ */ new Set(), this.state = {
|
|
374
373
|
isOpen: !1,
|
|
375
374
|
isTyping: !1,
|
|
376
375
|
isConnected: !1,
|
|
377
376
|
messages: []
|
|
378
|
-
}, this.historyKey = `spilki-history:${e}
|
|
377
|
+
}, this.historyKey = `spilki-history:${e}`, this.sessionKey = `spilki-session:${e}`, this.tokenKey = `spilki-token:${e}`, this.persist = t.persist, this.state.messages = this.loadMessages();
|
|
379
378
|
}
|
|
380
379
|
get snapshot() {
|
|
381
380
|
return { ...this.state, messages: [...this.state.messages] };
|
|
@@ -398,7 +397,7 @@ class B {
|
|
|
398
397
|
addMessage(e) {
|
|
399
398
|
var s, i;
|
|
400
399
|
const t = {
|
|
401
|
-
id: (s = e.id) != null ? s :
|
|
400
|
+
id: (s = e.id) != null ? s : B("msg"),
|
|
402
401
|
ts: (i = e.ts) != null ? i : Date.now(),
|
|
403
402
|
author: e.author,
|
|
404
403
|
text: e.text
|
|
@@ -415,8 +414,8 @@ class B {
|
|
|
415
414
|
if (!this.persist) return null;
|
|
416
415
|
try {
|
|
417
416
|
return localStorage.getItem(this.sessionKey);
|
|
418
|
-
} catch {
|
|
419
|
-
return null;
|
|
417
|
+
} catch (e) {
|
|
418
|
+
return console.error("SpilkiWidget: unable to get item", e), null;
|
|
420
419
|
}
|
|
421
420
|
}
|
|
422
421
|
persistSession(e) {
|
|
@@ -424,7 +423,7 @@ class B {
|
|
|
424
423
|
try {
|
|
425
424
|
localStorage.setItem(this.sessionKey, e);
|
|
426
425
|
} catch (t) {
|
|
427
|
-
console.
|
|
426
|
+
console.error("SpilkiWidget: unable to set item", t);
|
|
428
427
|
}
|
|
429
428
|
}
|
|
430
429
|
clearSession() {
|
|
@@ -432,7 +431,31 @@ class B {
|
|
|
432
431
|
try {
|
|
433
432
|
localStorage.removeItem(this.sessionKey);
|
|
434
433
|
} catch (e) {
|
|
435
|
-
console.
|
|
434
|
+
console.error("SpilkiWidget: unable to remove item", e);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
get accessToken() {
|
|
438
|
+
if (!this.persist) return null;
|
|
439
|
+
try {
|
|
440
|
+
return localStorage.getItem(this.tokenKey);
|
|
441
|
+
} catch (e) {
|
|
442
|
+
return console.error("SpilkiWidget: unable to get item", e), null;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
persistAccessToken(e) {
|
|
446
|
+
if (this.persist)
|
|
447
|
+
try {
|
|
448
|
+
localStorage.setItem(this.tokenKey, e);
|
|
449
|
+
} catch (t) {
|
|
450
|
+
console.error("SpilkiWidget: unable to set item", t);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
clearAccessToken() {
|
|
454
|
+
if (this.persist)
|
|
455
|
+
try {
|
|
456
|
+
localStorage.removeItem(this.tokenKey);
|
|
457
|
+
} catch (e) {
|
|
458
|
+
console.error("SpilkiWidget: unable to remove item", e);
|
|
436
459
|
}
|
|
437
460
|
}
|
|
438
461
|
emit() {
|
|
@@ -443,7 +466,7 @@ class B {
|
|
|
443
466
|
try {
|
|
444
467
|
localStorage.setItem(this.historyKey, JSON.stringify(this.state.messages));
|
|
445
468
|
} catch (e) {
|
|
446
|
-
console.
|
|
469
|
+
console.error("SpilkiWidget: unable to set item", e);
|
|
447
470
|
}
|
|
448
471
|
}
|
|
449
472
|
loadMessages() {
|
|
@@ -453,12 +476,12 @@ class B {
|
|
|
453
476
|
if (!e) return [];
|
|
454
477
|
const t = JSON.parse(e);
|
|
455
478
|
return Array.isArray(t) ? u(t, f) : [];
|
|
456
|
-
} catch {
|
|
457
|
-
return [];
|
|
479
|
+
} catch (e) {
|
|
480
|
+
return console.error("SpilkiWidget: unable to load messages", e), [];
|
|
458
481
|
}
|
|
459
482
|
}
|
|
460
483
|
}
|
|
461
|
-
function
|
|
484
|
+
function N(r) {
|
|
462
485
|
const e = r.replace(/-/g, "+").replace(/_/g, "/"), t = e.padEnd(e.length + (4 - e.length % 4) % 4, "=");
|
|
463
486
|
if (typeof atob == "function")
|
|
464
487
|
return decodeURIComponent(
|
|
@@ -469,24 +492,24 @@ function U(r) {
|
|
|
469
492
|
return s.from(t, "base64").toString("utf8");
|
|
470
493
|
throw new Error("SpilkiWidget: no base64 decoder available");
|
|
471
494
|
}
|
|
472
|
-
function
|
|
495
|
+
function D(r) {
|
|
473
496
|
if (!r) return null;
|
|
474
497
|
const e = r.split(".");
|
|
475
498
|
if (e.length < 2) return null;
|
|
476
499
|
try {
|
|
477
|
-
const t =
|
|
500
|
+
const t = N(e[1]);
|
|
478
501
|
return JSON.parse(t);
|
|
479
502
|
} catch (t) {
|
|
480
503
|
return console.error("SpilkiWidget: unable to parse JWT", t), null;
|
|
481
504
|
}
|
|
482
505
|
}
|
|
483
|
-
function
|
|
484
|
-
const e =
|
|
506
|
+
function F(r) {
|
|
507
|
+
const e = D(r);
|
|
485
508
|
if (!(e != null && e.exp)) return !1;
|
|
486
509
|
const t = Math.floor(Date.now() / 1e3);
|
|
487
510
|
return e.exp < t;
|
|
488
511
|
}
|
|
489
|
-
const
|
|
512
|
+
const z = {
|
|
490
513
|
onOpen() {
|
|
491
514
|
},
|
|
492
515
|
onClose() {
|
|
@@ -498,81 +521,107 @@ const D = {
|
|
|
498
521
|
onTransportChange() {
|
|
499
522
|
}
|
|
500
523
|
};
|
|
501
|
-
function
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
524
|
+
async function H(r, e, t) {
|
|
525
|
+
const s = `${r.replace(/\/$/, "")}/widget/install`, i = await fetch(s, {
|
|
526
|
+
method: "POST",
|
|
527
|
+
headers: { "Content-Type": "application/json", Origin: window.location.origin },
|
|
528
|
+
body: JSON.stringify({ token: e, organisationId: t })
|
|
529
|
+
});
|
|
530
|
+
if (!i.ok) throw new Error(`SpilkiWidget: install failed (${i.status})`);
|
|
531
|
+
return (await i.json()).accessToken;
|
|
532
|
+
}
|
|
533
|
+
async function q(r, e) {
|
|
534
|
+
const t = `${r.replace(/\/$/, "")}/widget/refresh`, s = await fetch(t, {
|
|
535
|
+
method: "POST",
|
|
536
|
+
headers: { Authorization: `Bearer ${e}`, Origin: window.location.origin }
|
|
537
|
+
});
|
|
538
|
+
if (!s.ok) throw new Error(`SpilkiWidget: refresh failed (${s.status})`);
|
|
539
|
+
return (await s.json()).accessToken;
|
|
540
|
+
}
|
|
541
|
+
function E(r) {
|
|
542
|
+
var k, w, y, S;
|
|
543
|
+
if (!r.org)
|
|
544
|
+
throw new Error("SpilkiWidget: org is required");
|
|
545
|
+
const e = $(r);
|
|
546
|
+
K(e.allowedOriginsHint);
|
|
547
|
+
const t = { ...z, ...(k = e.hooks) != null ? k : {} }, s = new U(e.org, { persist: e.persist });
|
|
548
|
+
let i = (w = s.accessToken) != null ? w : void 0;
|
|
549
|
+
const n = async () => {
|
|
550
|
+
if (!i) {
|
|
551
|
+
if (!r.installationToken) throw new Error("SpilkiWidget: missing installationToken");
|
|
552
|
+
if (!r.org) throw new Error("SpilkiWidget: missing org");
|
|
553
|
+
i = await H(e.apiBase, r.installationToken, r.org), s.persistAccessToken(i);
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
F(i) && (i = await q(e.apiBase, i), s.persistAccessToken(i));
|
|
557
|
+
}, l = M({
|
|
510
558
|
color: e.color,
|
|
511
|
-
position: (
|
|
559
|
+
position: (y = e.position) != null ? y : "bottom-right",
|
|
512
560
|
onClick: () => {
|
|
513
561
|
s.snapshot.isOpen ? (s.close(), t.onClose()) : (s.open(), t.onOpen());
|
|
514
562
|
}
|
|
515
|
-
}),
|
|
563
|
+
}), a = new C({
|
|
516
564
|
color: e.color,
|
|
517
|
-
theme:
|
|
518
|
-
position: (
|
|
565
|
+
theme: x(e.theme),
|
|
566
|
+
position: (S = e.position) != null ? S : "bottom-right",
|
|
519
567
|
i18n: e.i18n,
|
|
520
568
|
onClose: () => {
|
|
521
569
|
s.close(), t.onClose();
|
|
522
570
|
},
|
|
523
|
-
onSend: (
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
t.onError(
|
|
571
|
+
onSend: (o) => {
|
|
572
|
+
const c = s.addMessage({ author: "user", text: o });
|
|
573
|
+
a.appendMessage(c), n().then(() => h.send(o)).catch((I) => {
|
|
574
|
+
t.onError(I), s.setConnected(!1), a.setOffline(!0);
|
|
527
575
|
});
|
|
528
576
|
}
|
|
529
|
-
}),
|
|
577
|
+
}), h = new P(
|
|
530
578
|
{
|
|
531
579
|
apiBase: e.apiBase,
|
|
532
|
-
|
|
580
|
+
accessToken: i,
|
|
533
581
|
org: e.org,
|
|
534
|
-
assistant: e.assistant,
|
|
535
582
|
sessionId: s.sessionId
|
|
536
583
|
},
|
|
537
584
|
{
|
|
538
|
-
onOpen(
|
|
539
|
-
|
|
585
|
+
onOpen(o) {
|
|
586
|
+
m.transport = o, t.onTransportChange(o), s.setConnected(!0), a.setOffline(!1);
|
|
540
587
|
},
|
|
541
|
-
onMessage(
|
|
542
|
-
const
|
|
543
|
-
|
|
588
|
+
onMessage(o) {
|
|
589
|
+
const c = s.addMessage(o);
|
|
590
|
+
a.appendMessage(c), t.onMessage(c);
|
|
544
591
|
},
|
|
545
|
-
onTyping(
|
|
546
|
-
s.setTyping(
|
|
592
|
+
onTyping(o) {
|
|
593
|
+
s.setTyping(o);
|
|
547
594
|
},
|
|
548
|
-
onError(
|
|
549
|
-
t.onError(
|
|
595
|
+
onError(o) {
|
|
596
|
+
t.onError(o), s.setConnected(!1), s.snapshot.isOpen && a.setOffline(!0);
|
|
550
597
|
}
|
|
551
598
|
}
|
|
552
599
|
);
|
|
553
|
-
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
556
|
-
const
|
|
600
|
+
l.mount(), a.mount();
|
|
601
|
+
const b = s.snapshot.messages;
|
|
602
|
+
if (b.length === 0 && e.welcome) {
|
|
603
|
+
const o = {
|
|
557
604
|
id: "welcome",
|
|
558
605
|
author: "bot",
|
|
559
606
|
text: e.welcome,
|
|
560
607
|
ts: Date.now()
|
|
561
608
|
};
|
|
562
|
-
s.addMessage(
|
|
609
|
+
s.addMessage(o), a.appendMessage(o);
|
|
563
610
|
} else
|
|
564
|
-
|
|
565
|
-
const
|
|
566
|
-
const
|
|
567
|
-
|
|
611
|
+
a.updateMessages(b);
|
|
612
|
+
const T = s.subscribe(() => {
|
|
613
|
+
const o = s.snapshot;
|
|
614
|
+
l.setOpen(o.isOpen), a.setTyping(o.isTyping), a.setOffline(!o.isConnected), a.updateTheme(x(e.theme)), o.isOpen ? a.show() : a.hide();
|
|
568
615
|
});
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
616
|
+
n().then(
|
|
617
|
+
() => h.connect().then((o) => {
|
|
618
|
+
var c;
|
|
619
|
+
e.persist && s.persistSession(o.sessionId), s.setConnected(!0), t.onTransportChange((c = h.kind) != null ? c : "ws");
|
|
620
|
+
})
|
|
621
|
+
).catch((o) => {
|
|
622
|
+
t.onError(o), s.setConnected(!1), a.setOffline(!0);
|
|
574
623
|
});
|
|
575
|
-
const
|
|
624
|
+
const m = {
|
|
576
625
|
transport: null,
|
|
577
626
|
open() {
|
|
578
627
|
s.open(), t.onOpen();
|
|
@@ -581,39 +630,38 @@ function v(r) {
|
|
|
581
630
|
s.close(), t.onClose();
|
|
582
631
|
},
|
|
583
632
|
destroy() {
|
|
584
|
-
|
|
633
|
+
T(), h.stop(), l.destroy(), a.destroy();
|
|
585
634
|
}
|
|
586
635
|
};
|
|
587
|
-
return
|
|
636
|
+
return m;
|
|
588
637
|
}
|
|
589
|
-
function
|
|
590
|
-
var
|
|
638
|
+
function J() {
|
|
639
|
+
var s, i;
|
|
591
640
|
if (typeof document == "undefined") return;
|
|
592
641
|
const r = document.currentScript;
|
|
593
642
|
if (!r) return;
|
|
594
643
|
const e = r.dataset;
|
|
595
644
|
if (e.autoinit === "false") return;
|
|
596
|
-
const t = e.org
|
|
597
|
-
if (!t
|
|
598
|
-
console.error("SpilkiWidget: data-org and
|
|
645
|
+
const t = e.org;
|
|
646
|
+
if (!t) {
|
|
647
|
+
console.error("SpilkiWidget: data-org and is required for auto init");
|
|
599
648
|
return;
|
|
600
649
|
}
|
|
601
|
-
|
|
650
|
+
E({
|
|
602
651
|
org: t,
|
|
603
|
-
|
|
604
|
-
token: e.token,
|
|
652
|
+
installationToken: e.installationToken,
|
|
605
653
|
apiBase: e.apiBase,
|
|
606
|
-
position: (
|
|
607
|
-
theme: (
|
|
654
|
+
position: (s = e.position) != null ? s : void 0,
|
|
655
|
+
theme: (i = e.theme) != null ? i : void 0
|
|
608
656
|
});
|
|
609
657
|
}
|
|
610
658
|
if (typeof window != "undefined") {
|
|
611
659
|
const r = window;
|
|
612
|
-
r.SpilkiWidget = r.SpilkiWidget || {}, r.SpilkiWidget.init = (e) =>
|
|
660
|
+
r.SpilkiWidget = r.SpilkiWidget || {}, r.SpilkiWidget.init = (e) => E(e);
|
|
613
661
|
}
|
|
614
|
-
|
|
662
|
+
J();
|
|
615
663
|
export {
|
|
616
|
-
|
|
617
|
-
|
|
664
|
+
J as autoInit,
|
|
665
|
+
E as initSpilkiWidget
|
|
618
666
|
};
|
|
619
667
|
//# sourceMappingURL=widget.es.js.map
|