@spilki/widget 1.0.31 → 1.0.33
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/dist/bootstrap.es.js +229 -184
- package/dist/bootstrap.es.js.map +1 -1
- package/dist/bootstrap.umd.js +6 -6
- package/dist/bootstrap.umd.js.map +1 -1
- package/dist/core/state.d.ts +8 -2
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/transport.d.ts +2 -1
- package/dist/core/transport.d.ts.map +1 -1
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/panel.d.ts +2 -1
- package/dist/ui/panel.d.ts.map +1 -1
- package/dist/widget.es.js +229 -184
- package/dist/widget.es.js.map +1 -1
- package/dist/widget.umd.js +7 -7
- package/dist/widget.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const F = `
|
|
2
2
|
<style>
|
|
3
3
|
:host {
|
|
4
4
|
all: initial;
|
|
@@ -71,13 +71,13 @@ const R = `
|
|
|
71
71
|
<span class="badge" hidden aria-hidden="true">0</span>
|
|
72
72
|
</button>
|
|
73
73
|
`;
|
|
74
|
-
function
|
|
74
|
+
function R(o) {
|
|
75
75
|
const e = document.createElement("div");
|
|
76
|
-
e.setAttribute("part", "bubble-root"), e.setAttribute("data-position",
|
|
76
|
+
e.setAttribute("part", "bubble-root"), e.setAttribute("data-position", o.position), e.style.setProperty("--spilki-accent", o.color);
|
|
77
77
|
const t = e.attachShadow({ mode: "open" });
|
|
78
|
-
t.innerHTML =
|
|
78
|
+
t.innerHTML = F;
|
|
79
79
|
const s = t.querySelector("button"), i = t.querySelector(".badge");
|
|
80
|
-
return s.addEventListener("click", () =>
|
|
80
|
+
return s.addEventListener("click", () => o.onClick()), {
|
|
81
81
|
element: e,
|
|
82
82
|
mount() {
|
|
83
83
|
document.body.appendChild(e);
|
|
@@ -98,65 +98,68 @@ function K(r) {
|
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
const
|
|
101
|
+
const K = "https://api.spilki.app", C = {
|
|
102
102
|
welcome: "Hi! I'm your assistant.",
|
|
103
103
|
placeholder: "Type a message…",
|
|
104
104
|
sendLabel: "Send",
|
|
105
|
-
typing: "Assistant is typing
|
|
105
|
+
typing: "Assistant is typing",
|
|
106
|
+
thinking: "Assistant is thinking",
|
|
107
|
+
searching: "Searching",
|
|
108
|
+
executingTool: "Working on it",
|
|
106
109
|
offline: "Unable to connect. Please try again later.",
|
|
107
110
|
title: "Spilki Assistant"
|
|
108
|
-
},
|
|
109
|
-
apiBase:
|
|
111
|
+
}, w = {
|
|
112
|
+
apiBase: K,
|
|
110
113
|
position: "bottom-right",
|
|
111
114
|
theme: "auto",
|
|
112
115
|
color: "#6366f1",
|
|
113
|
-
welcome:
|
|
116
|
+
welcome: C.welcome,
|
|
114
117
|
persist: !0,
|
|
115
118
|
sound: !0,
|
|
116
|
-
i18n:
|
|
119
|
+
i18n: C
|
|
117
120
|
};
|
|
118
|
-
function H(
|
|
119
|
-
var t, s, i,
|
|
120
|
-
const e = { ...
|
|
121
|
+
function H(o) {
|
|
122
|
+
var t, s, i, r, a, n, l, g;
|
|
123
|
+
const e = { ...C, ...(t = o.i18n) != null ? t : {} };
|
|
121
124
|
return {
|
|
122
|
-
...
|
|
123
|
-
...
|
|
124
|
-
apiBase: (s =
|
|
125
|
+
...w,
|
|
126
|
+
...o,
|
|
127
|
+
apiBase: (s = o.apiBase) != null ? s : w.apiBase,
|
|
125
128
|
i18n: e,
|
|
126
|
-
welcome: (i =
|
|
127
|
-
position: (
|
|
128
|
-
theme: (a =
|
|
129
|
-
color: (n =
|
|
130
|
-
persist: (l =
|
|
131
|
-
sound: (g =
|
|
129
|
+
welcome: (i = o.welcome) != null ? i : e.welcome,
|
|
130
|
+
position: (r = o.position) != null ? r : w.position,
|
|
131
|
+
theme: (a = o.theme) != null ? a : w.theme,
|
|
132
|
+
color: (n = o.color) != null ? n : w.color,
|
|
133
|
+
persist: (l = o.persist) != null ? l : w.persist,
|
|
134
|
+
sound: (g = o.sound) != null ? g : w.sound
|
|
132
135
|
};
|
|
133
136
|
}
|
|
134
|
-
function z(
|
|
135
|
-
return typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${
|
|
137
|
+
function z(o = "msg") {
|
|
138
|
+
return typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${o}-${Math.random().toString(16).slice(2)}`;
|
|
136
139
|
}
|
|
137
|
-
function
|
|
138
|
-
var
|
|
139
|
-
return (e = (
|
|
140
|
+
function _() {
|
|
141
|
+
var o, e;
|
|
142
|
+
return (e = (o = window.matchMedia) == null ? void 0 : o.call(window, "(prefers-color-scheme: dark)").matches) != null ? e : !1;
|
|
140
143
|
}
|
|
141
|
-
function
|
|
142
|
-
return
|
|
144
|
+
function P(o) {
|
|
145
|
+
return o === "light" || o === "dark" ? o : _() ? "dark" : "light";
|
|
143
146
|
}
|
|
144
|
-
function x(
|
|
145
|
-
return
|
|
147
|
+
function x(o, e = 30) {
|
|
148
|
+
return o.slice(-e);
|
|
146
149
|
}
|
|
147
|
-
function
|
|
148
|
-
if (!
|
|
150
|
+
function G(o) {
|
|
151
|
+
if (!o || o.length === 0) return;
|
|
149
152
|
const e = window.location.origin;
|
|
150
|
-
|
|
151
|
-
`SpilkiWidget: current origin ${e} not in allowedOriginsHint: ${
|
|
153
|
+
o.includes(e) || console.warn(
|
|
154
|
+
`SpilkiWidget: current origin ${e} not in allowedOriginsHint: ${o.join(", ")}`
|
|
152
155
|
);
|
|
153
156
|
}
|
|
154
|
-
const
|
|
155
|
-
function
|
|
156
|
-
const e = new Date(
|
|
157
|
-
return n ===
|
|
157
|
+
const q = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
158
|
+
function Y(o) {
|
|
159
|
+
const e = new Date(o), t = /* @__PURE__ */ new Date(), s = (l) => String(l).padStart(2, "0"), i = `${s(e.getHours())}:${s(e.getMinutes())}`, r = new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime(), a = r - 864e5, n = new Date(e.getFullYear(), e.getMonth(), e.getDate()).getTime();
|
|
160
|
+
return n === r ? `Today at ${i}` : n === a ? `Yesterday at ${i}` : `${q[e.getMonth()]} ${e.getDate()}, ${i}`;
|
|
158
161
|
}
|
|
159
|
-
const
|
|
162
|
+
const V = ':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-muted-light: #64748b;--spilki-muted-dark: #94a3b8;--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{position:relative;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 button.close:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}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:.75rem;scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent;scroll-behavior:smooth}.message{display:flex;flex-direction:column;gap:.15rem;max-width:85%;width:fit-content;line-height:1.4;word-wrap:break-word;overflow-wrap:anywhere;white-space:pre-wrap}.message.user{align-self:flex-end;align-items:flex-end}.message .bubble{padding:.6rem .8rem;border-radius:1rem;background:#6366f126}.message.user .bubble{background:var(--spilki-accent);color:#fff}.message.bot .bubble{background:#94a3b826}.msg-time{font-size:.7rem;color:var(--spilki-muted);margin-top:2px}.date-separator{display:flex;align-items:center;gap:.5rem;padding:.4rem 0;font-size:.72rem;color:var(--spilki-muted);white-space:nowrap}.date-separator:before,.date-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.scroll-bottom{position:absolute;right:1rem;bottom:88px;width:38px;height:38px;border:none;border-radius:999px;background:var(--spilki-accent);color:#fff;box-shadow:0 8px 20px #0f172a40;cursor:pointer;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .18s ease,transform .18s ease;z-index:3}.scroll-bottom.visible{opacity:1;pointer-events:auto;transform:translateY(0)}.scroll-arrow{font-size:.8rem;line-height:1}.scroll-count{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;border-radius:999px;background:#ef4444;color:#fff;font-size:10px;line-height:16px;text-align:center;padding:0 4px}.suggested-replies{display:flex;flex-wrap:wrap;gap:.4rem;padding:.5rem 1rem;border-top:1px solid var(--spilki-border)}.suggested-chip{border:1px solid var(--spilki-accent);background:transparent;color:var(--spilki-accent);border-radius:999px;padding:.35rem .75rem;font-size:.8rem;font-family:inherit;cursor:pointer;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:background .15s,color .15s}.suggested-chip:hover{background:var(--spilki-accent);color:#fff}.suggested-chip:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.input-area{padding:.5rem .75rem}.input-wrap{display:flex;align-items:center;border:1px solid var(--spilki-border);border-radius:1.5rem;background:transparent;padding-left:0}.input-area textarea{flex:1;resize:none;min-height:2.4rem;max-height:6rem;border:0;border-radius:0;outline:0;background:transparent;box-shadow:none;-webkit-box-shadow:none;-webkit-appearance:none;appearance:none;padding:.55rem 0 .55rem 1rem;font-family:inherit;font-size:.95rem;color:var(--spilki-text);scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent}.input-actions{display:flex;align-items:center;gap:.25rem;padding:.25rem .35rem;flex-shrink:0}.input-actions button{width:32px;height:32px;display:grid;place-items:center;border:none;border-radius:50%;cursor:pointer;padding:0;transition:opacity .15s}.emoji-btn{background:#6366f126;color:var(--spilki-accent)}.emoji-btn:hover{background:#6366f140}.emoji-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:1px}.send-btn{background:var(--spilki-accent);color:#fff}.send-btn:hover{opacity:.85}.send-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.emoji-picker{position:absolute;right:1rem;bottom:80px;width:240px;max-height:180px;overflow-y:auto;display:none;grid-template-columns:repeat(10,minmax(0,1fr));gap:.25rem;padding:.5rem;background:var(--spilki-surface);border:1px solid var(--spilki-border);border-radius:12px;box-shadow:0 14px 30px #0f172a40;z-index:4}.emoji-option{width:100%;aspect-ratio:1;border:none;border-radius:8px;background:transparent;font-size:1rem;cursor:pointer}.emoji-option:hover,.emoji-option:focus-visible{background:#94a3b833}.typing{font-size:.75rem;color:var(--spilki-muted);padding:0 1rem .75rem}.typing:after{content:"";animation:dots 1.2s steps(4,end) infinite}@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}.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);--spilki-muted: var(--spilki-muted-dark)}:host([data-theme="dark"]) .messages,:host([data-theme="dark"]) .input-area textarea,:host([data-theme="dark"]) .emoji-picker{scrollbar-color:rgba(255,255,255,.2) transparent}:host([data-theme="light"]){--spilki-surface: var(--spilki-bg-light);--spilki-text: var(--spilki-text-light);--spilki-border: var(--spilki-border-light);--spilki-muted: var(--spilki-muted-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:transparent}.messages::-webkit-scrollbar,.input-area textarea::-webkit-scrollbar,.emoji-picker::-webkit-scrollbar{width:6px}.messages::-webkit-scrollbar-track,.input-area textarea::-webkit-scrollbar-track,.emoji-picker::-webkit-scrollbar-track{background:transparent}.messages::-webkit-scrollbar-thumb,.input-area textarea::-webkit-scrollbar-thumb,.emoji-picker::-webkit-scrollbar-thumb{background:#94a3b84d;border-radius:999px}.messages::-webkit-scrollbar-thumb:hover,.input-area textarea::-webkit-scrollbar-thumb:hover,.emoji-picker::-webkit-scrollbar-thumb:hover{background:#94a3b880}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .emoji-picker::-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,:host([data-theme="dark"]) .emoji-picker::-webkit-scrollbar-thumb:hover{background:#ffffff59}.conversation-separator{display:flex;align-items:center;gap:.5rem;padding:.5rem 0;cursor:pointer;user-select:none;font-size:.7rem;color:var(--spilki-muted);white-space:nowrap}.conversation-separator:before,.conversation-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.conversation-separator:hover{color:var(--spilki-text)}.conversation-separator:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}.conversation-history{display:none;flex-direction:column;gap:.5rem}.conversation-history.expanded{display:flex}', j = 24 * 60 * 60 * 1e3, J = 2 * 60 * 1e3, X = 200, Z = [
|
|
160
163
|
"😀",
|
|
161
164
|
"😂",
|
|
162
165
|
"🤣",
|
|
@@ -208,8 +211,8 @@ const Y = ':host{--spilki-bg-light: #ffffff;--spilki-bg-dark: #0f172a;--spilki-t
|
|
|
208
211
|
"☕",
|
|
209
212
|
"🍕"
|
|
210
213
|
];
|
|
211
|
-
function
|
|
212
|
-
return
|
|
214
|
+
function E(o) {
|
|
215
|
+
return o.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
213
216
|
}
|
|
214
217
|
class Q {
|
|
215
218
|
constructor(e) {
|
|
@@ -226,9 +229,9 @@ class Q {
|
|
|
226
229
|
day: "numeric",
|
|
227
230
|
year: "numeric"
|
|
228
231
|
}), this.renderedMessages = [], this.focusable = [], this.seenIds = /* @__PURE__ */ new Set(), this.lastTimelineMessage = null, this.scrollUnreadCount = 0, this.emojiPickerOpen = !1, 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" });
|
|
229
|
-
const t =
|
|
232
|
+
const t = E(e.i18n.title), s = E(e.i18n.typing), i = E(e.i18n.offline), r = E(e.i18n.placeholder), a = E(e.i18n.sendLabel);
|
|
230
233
|
this.shadow.innerHTML = `
|
|
231
|
-
<style>${
|
|
234
|
+
<style>${V}</style>
|
|
232
235
|
<div class="wrapper" role="dialog" aria-modal="true" aria-label="${t}">
|
|
233
236
|
<header>
|
|
234
237
|
<h1><span class="status-dot" aria-hidden="true"></span>${t}</h1>
|
|
@@ -245,7 +248,7 @@ class Q {
|
|
|
245
248
|
<div class="emoji-picker" aria-label="Emoji picker"></div>
|
|
246
249
|
<div class="input-area">
|
|
247
250
|
<div class="input-wrap">
|
|
248
|
-
<textarea rows="1" placeholder="${
|
|
251
|
+
<textarea rows="1" placeholder="${r}" aria-label="${r}"></textarea>
|
|
249
252
|
<div class="input-actions">
|
|
250
253
|
<button class="emoji-btn" type="button" aria-label="Insert emoji">
|
|
251
254
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
@@ -326,7 +329,7 @@ class Q {
|
|
|
326
329
|
this.messagesEl.innerHTML = "", this.seenIds.clear(), this.renderedMessages.length = 0, this.lastTimelineMessage = null;
|
|
327
330
|
for (const s of e) {
|
|
328
331
|
s.messages.forEach((n) => this.seenIds.add(n.id));
|
|
329
|
-
const i = this.createHistoryContainer(s.messages),
|
|
332
|
+
const i = this.createHistoryContainer(s.messages), r = s.messages[s.messages.length - 1].ts, a = this.createSeparatorElement(r, i);
|
|
330
333
|
this.messagesEl.appendChild(i), this.messagesEl.appendChild(a);
|
|
331
334
|
}
|
|
332
335
|
t.forEach((s) => {
|
|
@@ -355,6 +358,20 @@ class Q {
|
|
|
355
358
|
hideSuggestedReplies() {
|
|
356
359
|
this.suggestedRepliesEl.toggleAttribute("hidden", !0), this.suggestedRepliesEl.replaceChildren(), this.collectFocusable(), this.focusInput();
|
|
357
360
|
}
|
|
361
|
+
setAgentActivity(e, t) {
|
|
362
|
+
var i;
|
|
363
|
+
if (e === null) {
|
|
364
|
+
this.typingEl.toggleAttribute("hidden", !0);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const s = {
|
|
368
|
+
TYPING: t.typing,
|
|
369
|
+
THINKING: t.thinking,
|
|
370
|
+
SEARCHING: t.searching,
|
|
371
|
+
EXECUTING_TOOL: t.executingTool
|
|
372
|
+
};
|
|
373
|
+
this.typingEl.textContent = (i = s[e]) != null ? i : t.typing, this.typingEl.toggleAttribute("hidden", !1);
|
|
374
|
+
}
|
|
358
375
|
setTyping(e) {
|
|
359
376
|
this.typingEl.toggleAttribute("hidden", !e);
|
|
360
377
|
}
|
|
@@ -378,16 +395,16 @@ class Q {
|
|
|
378
395
|
}
|
|
379
396
|
createSeparatorElement(e, t) {
|
|
380
397
|
const s = document.createElement("div");
|
|
381
|
-
s.className = "conversation-separator", s.setAttribute("role", "button"), s.setAttribute("tabindex", "0"), s.setAttribute("aria-expanded", "false"), s.setAttribute("aria-label", "Show previous conversation"), s.textContent =
|
|
398
|
+
s.className = "conversation-separator", s.setAttribute("role", "button"), s.setAttribute("tabindex", "0"), s.setAttribute("aria-expanded", "false"), s.setAttribute("aria-label", "Show previous conversation"), s.textContent = Y(e);
|
|
382
399
|
const i = () => {
|
|
383
|
-
const
|
|
384
|
-
s.setAttribute("aria-expanded", String(
|
|
400
|
+
const r = t.classList.toggle("expanded");
|
|
401
|
+
s.setAttribute("aria-expanded", String(r)), s.setAttribute(
|
|
385
402
|
"aria-label",
|
|
386
|
-
|
|
403
|
+
r ? "Hide previous conversation" : "Show previous conversation"
|
|
387
404
|
);
|
|
388
405
|
};
|
|
389
|
-
return s.addEventListener("click", i), s.addEventListener("keydown", (
|
|
390
|
-
const a =
|
|
406
|
+
return s.addEventListener("click", i), s.addEventListener("keydown", (r) => {
|
|
407
|
+
const a = r;
|
|
391
408
|
(a.key === "Enter" || a.key === " ") && (a.preventDefault(), i());
|
|
392
409
|
}), s;
|
|
393
410
|
}
|
|
@@ -397,8 +414,8 @@ class Q {
|
|
|
397
414
|
let s = null;
|
|
398
415
|
return e.forEach((i) => {
|
|
399
416
|
this.appendDateSeparatorIfNeeded(s, i, t);
|
|
400
|
-
const { item:
|
|
401
|
-
t.appendChild(
|
|
417
|
+
const { item: r } = this.createMessageElement(i);
|
|
418
|
+
t.appendChild(r), s = i;
|
|
402
419
|
}), t;
|
|
403
420
|
}
|
|
404
421
|
appendTimelineMessage(e) {
|
|
@@ -414,24 +431,24 @@ class Q {
|
|
|
414
431
|
}
|
|
415
432
|
updateTimestampVisibility() {
|
|
416
433
|
for (let e = 0; e < this.renderedMessages.length; e += 1) {
|
|
417
|
-
const t = this.renderedMessages[e], s = this.renderedMessages[e + 1], i = !!s && s.message.author === t.message.author && s.message.ts - t.message.ts <=
|
|
434
|
+
const t = this.renderedMessages[e], s = this.renderedMessages[e + 1], i = !!s && s.message.author === t.message.author && s.message.ts - t.message.ts <= J && s.message.ts >= t.message.ts;
|
|
418
435
|
t.timeEl.toggleAttribute("hidden", i), t.timeEl.textContent = this.formatMessageTimestamp(t.message.ts);
|
|
419
436
|
}
|
|
420
437
|
}
|
|
421
438
|
formatMessageTimestamp(e) {
|
|
422
439
|
const s = Date.now() - e;
|
|
423
|
-
if (s <
|
|
440
|
+
if (s < j) {
|
|
424
441
|
const i = Math.max(1, Math.round(s / 6e4));
|
|
425
442
|
if (i < 60)
|
|
426
443
|
return this.relativeTimeFormat.format(-i, "minute");
|
|
427
|
-
const
|
|
428
|
-
return this.relativeTimeFormat.format(-
|
|
444
|
+
const r = Math.max(1, Math.round(i / 60));
|
|
445
|
+
return this.relativeTimeFormat.format(-r, "hour");
|
|
429
446
|
}
|
|
430
447
|
return this.absoluteTimeFormat.format(new Date(e));
|
|
431
448
|
}
|
|
432
449
|
formatDateSeparator(e) {
|
|
433
450
|
const t = new Date(e), s = this.startOfDay(Date.now()), i = this.startOfDay(e);
|
|
434
|
-
return i === s ? "Today" : i === s -
|
|
451
|
+
return i === s ? "Today" : i === s - j ? "Yesterday" : this.dateSeparatorFormat.format(t);
|
|
435
452
|
}
|
|
436
453
|
isSameDay(e, t) {
|
|
437
454
|
return this.startOfDay(e) === this.startOfDay(t);
|
|
@@ -499,8 +516,8 @@ class Q {
|
|
|
499
516
|
var a, n;
|
|
500
517
|
const t = this.input.value, s = (a = this.input.selectionStart) != null ? a : t.length, i = (n = this.input.selectionEnd) != null ? n : t.length;
|
|
501
518
|
this.input.value = `${t.slice(0, s)}${e}${t.slice(i)}`;
|
|
502
|
-
const
|
|
503
|
-
this.input.setSelectionRange(
|
|
519
|
+
const r = s + e.length;
|
|
520
|
+
this.input.setSelectionRange(r, r), this.input.dispatchEvent(new Event("input", { bubbles: !0 })), this.input.focus();
|
|
504
521
|
}
|
|
505
522
|
collectFocusable() {
|
|
506
523
|
const e = this.shadow.querySelectorAll(
|
|
@@ -516,10 +533,10 @@ class Q {
|
|
|
516
533
|
e.shiftKey && i === t ? (e.preventDefault(), s.focus()) : !e.shiftKey && i === s && (e.preventDefault(), t.focus());
|
|
517
534
|
}
|
|
518
535
|
}
|
|
519
|
-
const
|
|
536
|
+
const v = 1500, D = 8e3;
|
|
520
537
|
class ee {
|
|
521
538
|
constructor(e, t) {
|
|
522
|
-
this.sessionId = null, this.currentKind = null, this.stopped = !1, this.backoff =
|
|
539
|
+
this.sessionId = null, this.currentKind = null, this.stopped = !1, this.backoff = v, this.connectPromise = null, this.options = e, this.handlers = t;
|
|
523
540
|
}
|
|
524
541
|
setAccessToken(e) {
|
|
525
542
|
this.options.accessToken = e;
|
|
@@ -560,8 +577,8 @@ class ee {
|
|
|
560
577
|
});
|
|
561
578
|
if (!i.ok)
|
|
562
579
|
throw new Error(`SpilkiWidget: connect failed (${i.status})`);
|
|
563
|
-
const
|
|
564
|
-
return this.sessionId =
|
|
580
|
+
const r = await i.json();
|
|
581
|
+
return this.sessionId = r.sessionId, this.options.sessionId = r.sessionId, this.backoff = v, await this.startTransport(r), r;
|
|
565
582
|
}
|
|
566
583
|
async send(e, t) {
|
|
567
584
|
var a, n;
|
|
@@ -576,7 +593,7 @@ class ee {
|
|
|
576
593
|
this.ws.send(JSON.stringify({ type: "message", payload: s }));
|
|
577
594
|
return;
|
|
578
595
|
}
|
|
579
|
-
const i = `${this.options.apiBase.replace(/\/$/, "")}/widget/message`,
|
|
596
|
+
const i = `${this.options.apiBase.replace(/\/$/, "")}/widget/message`, r = await fetch(i, {
|
|
580
597
|
method: "POST",
|
|
581
598
|
headers: {
|
|
582
599
|
"Content-Type": "application/json",
|
|
@@ -584,12 +601,12 @@ class ee {
|
|
|
584
601
|
},
|
|
585
602
|
body: JSON.stringify(s)
|
|
586
603
|
});
|
|
587
|
-
if (!
|
|
588
|
-
throw new Error(`SpilkiWidget: send failed (${
|
|
604
|
+
if (!r.ok)
|
|
605
|
+
throw new Error(`SpilkiWidget: send failed (${r.status})`);
|
|
589
606
|
}
|
|
590
607
|
// #1: accept resetBackoff param; #8 #9: clear retryTimer
|
|
591
608
|
stop(e = !0) {
|
|
592
|
-
this.stopped = !0, e && (this.backoff =
|
|
609
|
+
this.stopped = !0, e && (this.backoff = v), this.retryTimer && (clearTimeout(this.retryTimer), this.retryTimer = void 0), this.ws && (this.wsOnOpen && this.ws.removeEventListener("open", this.wsOnOpen), this.wsOnMessage && this.ws.removeEventListener("message", this.wsOnMessage), this.wsOnClose && this.ws.removeEventListener("close", this.wsOnClose), this.wsOnError && this.ws.removeEventListener("error", this.wsOnError), this.ws.close(), this.ws = void 0), this.wsOnOpen = this.wsOnMessage = this.wsOnClose = this.wsOnError = void 0, this.sseAbort && (this.sseAbort.abort(), this.sseAbort = void 0), this.pollTimer && (clearTimeout(this.pollTimer), this.pollTimer = void 0), this.currentKind = null;
|
|
593
610
|
}
|
|
594
611
|
async startTransport(e) {
|
|
595
612
|
if (this.stopped) return;
|
|
@@ -614,8 +631,8 @@ class ee {
|
|
|
614
631
|
i.close();
|
|
615
632
|
return;
|
|
616
633
|
}
|
|
617
|
-
this.currentKind = "ws", this.handlers.onOpen("ws"), this.backoff =
|
|
618
|
-
}, this.wsOnMessage = (
|
|
634
|
+
this.currentKind = "ws", this.handlers.onOpen("ws"), this.backoff = v, t();
|
|
635
|
+
}, this.wsOnMessage = (r) => this.handleIncoming(r.data), this.wsOnClose = () => {
|
|
619
636
|
this.stopped || this.retryFallback("ws");
|
|
620
637
|
}, this.wsOnError = () => {
|
|
621
638
|
this.handlers.onError(new Error("SpilkiWidget: websocket error")), i.readyState !== WebSocket.OPEN && s(new Error("WebSocket failed"));
|
|
@@ -635,8 +652,8 @@ class ee {
|
|
|
635
652
|
"X-Authorization": `Bearer ${this.options.accessToken}`
|
|
636
653
|
},
|
|
637
654
|
signal: i.signal
|
|
638
|
-
}).then((
|
|
639
|
-
if (!
|
|
655
|
+
}).then((r) => {
|
|
656
|
+
if (!r.ok || !r.body) {
|
|
640
657
|
s(new Error("SSE failed"));
|
|
641
658
|
return;
|
|
642
659
|
}
|
|
@@ -644,39 +661,39 @@ class ee {
|
|
|
644
661
|
i.abort();
|
|
645
662
|
return;
|
|
646
663
|
}
|
|
647
|
-
this.currentKind = "sse", this.handlers.onOpen("sse"), this.backoff =
|
|
648
|
-
const a =
|
|
664
|
+
this.currentKind = "sse", this.handlers.onOpen("sse"), this.backoff = v, t();
|
|
665
|
+
const a = r.body.getReader(), n = new TextDecoder();
|
|
649
666
|
let l = "";
|
|
650
667
|
const g = () => {
|
|
651
|
-
a.read().then(({ done:
|
|
652
|
-
var
|
|
653
|
-
if (
|
|
668
|
+
a.read().then(({ done: u, value: h }) => {
|
|
669
|
+
var m;
|
|
670
|
+
if (u || this.stopped) {
|
|
654
671
|
this.stopped || (this.handlers.onError(new Error("SpilkiWidget: SSE stream ended")), this.retryFallback("sse"));
|
|
655
672
|
return;
|
|
656
673
|
}
|
|
657
|
-
l += n.decode(
|
|
658
|
-
const
|
|
674
|
+
l += n.decode(h, { stream: !0 });
|
|
675
|
+
const d = l.split(`
|
|
659
676
|
|
|
660
677
|
`);
|
|
661
|
-
l = (
|
|
662
|
-
for (const
|
|
663
|
-
for (const p of
|
|
678
|
+
l = (m = d.pop()) != null ? m : "";
|
|
679
|
+
for (const f of d)
|
|
680
|
+
for (const p of f.split(`
|
|
664
681
|
`))
|
|
665
682
|
p.startsWith("data:") && this.handleIncoming(p.slice(5).trim());
|
|
666
683
|
g();
|
|
667
|
-
}).catch((
|
|
668
|
-
i.signal.aborted || (this.handlers.onError(
|
|
684
|
+
}).catch((u) => {
|
|
685
|
+
i.signal.aborted || (this.handlers.onError(u), this.stopped || this.retryFallback("sse"));
|
|
669
686
|
});
|
|
670
687
|
};
|
|
671
688
|
g();
|
|
672
|
-
}).catch((
|
|
673
|
-
i.signal.aborted || s(
|
|
689
|
+
}).catch((r) => {
|
|
690
|
+
i.signal.aborted || s(r);
|
|
674
691
|
});
|
|
675
692
|
});
|
|
676
693
|
}
|
|
677
694
|
// #15: add auth header to poll fetch
|
|
678
695
|
async startPoll(e) {
|
|
679
|
-
this.currentKind = "poll", this.handlers.onOpen("poll"), this.backoff =
|
|
696
|
+
this.currentKind = "poll", this.handlers.onOpen("poll"), this.backoff = v;
|
|
680
697
|
const t = async () => {
|
|
681
698
|
if (!this.stopped)
|
|
682
699
|
try {
|
|
@@ -687,7 +704,7 @@ class ee {
|
|
|
687
704
|
});
|
|
688
705
|
if (!s.ok) throw new Error(`Poll failed ${s.status}`);
|
|
689
706
|
const i = await s.json();
|
|
690
|
-
x(i).forEach((
|
|
707
|
+
x(i).forEach((r) => this.handlers.onMessage(r)), this.backoff = v;
|
|
691
708
|
} catch (s) {
|
|
692
709
|
this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5, D);
|
|
693
710
|
} finally {
|
|
@@ -718,18 +735,24 @@ class ee {
|
|
|
718
735
|
dispatchIncoming(e) {
|
|
719
736
|
var t;
|
|
720
737
|
if ("type" in e) {
|
|
721
|
-
e.type === "message" ? this.handlers.onMessage(e.payload) : e.type === "typing"
|
|
738
|
+
e.type === "message" ? this.handlers.onMessage(e.payload) : e.type === "typing" ? this.handlers.onTyping(!!((t = e.payload) != null && t.active)) : e.type === "AGENT_EVENT" && se(e.payload) && this.handlers.onAgentEvent(e.payload);
|
|
722
739
|
return;
|
|
723
740
|
}
|
|
724
741
|
this.handlers.onMessage(e);
|
|
725
742
|
}
|
|
726
743
|
}
|
|
727
|
-
const
|
|
728
|
-
|
|
744
|
+
const te = /* @__PURE__ */ new Set(["TYPING", "THINKING", "SEARCHING", "EXECUTING_TOOL"]);
|
|
745
|
+
function se(o) {
|
|
746
|
+
if (typeof o != "object" || o === null) return !1;
|
|
747
|
+
const e = o;
|
|
748
|
+
return te.has(e.eventType) && typeof e.active == "boolean";
|
|
749
|
+
}
|
|
750
|
+
const L = 30 * 60 * 1e3, ie = 3e4, T = 30;
|
|
751
|
+
class oe {
|
|
729
752
|
constructor(e, t) {
|
|
730
|
-
this.org = e, this.listeners = /* @__PURE__ */ new Set(), this.state = {
|
|
753
|
+
this.org = e, this.listeners = /* @__PURE__ */ new Set(), this.activityTimer = null, this.activeEvents = /* @__PURE__ */ new Set(), this.state = {
|
|
731
754
|
isOpen: !1,
|
|
732
|
-
|
|
755
|
+
agentActivity: null,
|
|
733
756
|
isConnected: !1,
|
|
734
757
|
messages: []
|
|
735
758
|
}, this.historyKey = `spilki-history:${e}`, this.sessionKey = `spilki-session:${e}`, this.tokenKey = `spilki-token:${e}`, this.activityKey = `spilki-activity:${e}`, this.lastReadKey = `spilki-lastread:${e}`, this.persist = t.persist, this.state.messages = this.loadMessages();
|
|
@@ -737,7 +760,7 @@ class te {
|
|
|
737
760
|
get snapshot() {
|
|
738
761
|
return {
|
|
739
762
|
isOpen: this.state.isOpen,
|
|
740
|
-
|
|
763
|
+
agentActivity: this.state.agentActivity,
|
|
741
764
|
isConnected: this.state.isConnected,
|
|
742
765
|
messages: this.state.messages
|
|
743
766
|
};
|
|
@@ -751,8 +774,27 @@ class te {
|
|
|
751
774
|
close() {
|
|
752
775
|
this.state.isOpen && (this.state.isOpen = !1, this.emit());
|
|
753
776
|
}
|
|
777
|
+
handleAgentEvent(e, t) {
|
|
778
|
+
t ? this.activeEvents.add(e) : this.activeEvents.delete(e), this.updateDisplayedActivity();
|
|
779
|
+
}
|
|
754
780
|
setTyping(e) {
|
|
755
|
-
this.
|
|
781
|
+
this.handleAgentEvent("TYPING", e);
|
|
782
|
+
}
|
|
783
|
+
updateDisplayedActivity() {
|
|
784
|
+
this.activityTimer && (clearTimeout(this.activityTimer), this.activityTimer = null), this.activeEvents.size > 0 && (this.activityTimer = setTimeout(() => {
|
|
785
|
+
this.activeEvents.clear(), this.state.agentActivity = null, this.activityTimer = null, this.emit();
|
|
786
|
+
}, ie));
|
|
787
|
+
const e = this.resolveTopActivity();
|
|
788
|
+
this.state.agentActivity !== e && (this.state.agentActivity = e, this.emit());
|
|
789
|
+
}
|
|
790
|
+
resolveTopActivity() {
|
|
791
|
+
var t;
|
|
792
|
+
return this.activeEvents.size === 0 ? null : (t = [
|
|
793
|
+
"EXECUTING_TOOL",
|
|
794
|
+
"SEARCHING",
|
|
795
|
+
"THINKING",
|
|
796
|
+
"TYPING"
|
|
797
|
+
].find((s) => this.activeEvents.has(s))) != null ? t : null;
|
|
756
798
|
}
|
|
757
799
|
setConnected(e) {
|
|
758
800
|
this.state.isConnected !== e && (this.state.isConnected = e, this.emit());
|
|
@@ -765,10 +807,10 @@ class te {
|
|
|
765
807
|
author: e.author,
|
|
766
808
|
text: e.text
|
|
767
809
|
};
|
|
768
|
-
return this.state.messages.some((
|
|
810
|
+
return this.state.messages.some((r) => r.id === t.id) ? null : (this.state.messages = x([...this.state.messages, t], T), this.persistMessages(), this.touchActivity(), this.emit(), t);
|
|
769
811
|
}
|
|
770
812
|
setMessages(e) {
|
|
771
|
-
this.state.messages = x(e,
|
|
813
|
+
this.state.messages = x(e, T), this.persistMessages(), this.emit();
|
|
772
814
|
}
|
|
773
815
|
clearMessages() {
|
|
774
816
|
this.state.messages = [], this.persistMessages(), this.emit();
|
|
@@ -888,14 +930,14 @@ class te {
|
|
|
888
930
|
const e = localStorage.getItem(this.historyKey);
|
|
889
931
|
if (!e) return [];
|
|
890
932
|
const t = JSON.parse(e);
|
|
891
|
-
return Array.isArray(t) ? x(t,
|
|
933
|
+
return Array.isArray(t) ? x(t, T) : [];
|
|
892
934
|
} catch (e) {
|
|
893
935
|
return console.error("SpilkiWidget: unable to load messages", e), [];
|
|
894
936
|
}
|
|
895
937
|
}
|
|
896
938
|
}
|
|
897
|
-
function
|
|
898
|
-
const e =
|
|
939
|
+
function re(o) {
|
|
940
|
+
const e = o.replace(/-/g, "+").replace(/_/g, "/"), t = e.padEnd(e.length + (4 - e.length % 4) % 4, "=");
|
|
899
941
|
if (typeof atob == "function")
|
|
900
942
|
return decodeURIComponent(
|
|
901
943
|
Array.prototype.map.call(atob(t), (i) => `%${`00${i.charCodeAt(0).toString(16)}`.slice(-2)}`).join("")
|
|
@@ -905,24 +947,24 @@ function se(r) {
|
|
|
905
947
|
return s.from(t, "base64").toString("utf8");
|
|
906
948
|
throw new Error("SpilkiWidget: no base64 decoder available");
|
|
907
949
|
}
|
|
908
|
-
function
|
|
909
|
-
if (!
|
|
910
|
-
const e =
|
|
950
|
+
function ne(o) {
|
|
951
|
+
if (!o) return null;
|
|
952
|
+
const e = o.split(".");
|
|
911
953
|
if (e.length < 2) return null;
|
|
912
954
|
try {
|
|
913
|
-
const t =
|
|
955
|
+
const t = re(e[1]);
|
|
914
956
|
return JSON.parse(t);
|
|
915
957
|
} catch (t) {
|
|
916
958
|
return console.error("SpilkiWidget: unable to parse JWT", t), null;
|
|
917
959
|
}
|
|
918
960
|
}
|
|
919
|
-
function
|
|
920
|
-
const e =
|
|
961
|
+
function ae(o) {
|
|
962
|
+
const e = ne(o);
|
|
921
963
|
if (!(e != null && e.exp) || typeof e.exp != "number") return !0;
|
|
922
964
|
const t = Math.floor(Date.now() / 1e3);
|
|
923
965
|
return e.exp < t + 60;
|
|
924
966
|
}
|
|
925
|
-
const
|
|
967
|
+
const le = {
|
|
926
968
|
onOpen() {
|
|
927
969
|
},
|
|
928
970
|
onClose() {
|
|
@@ -934,8 +976,8 @@ const oe = {
|
|
|
934
976
|
onTransportChange() {
|
|
935
977
|
}
|
|
936
978
|
};
|
|
937
|
-
async function
|
|
938
|
-
const s = `${
|
|
979
|
+
async function ce(o, e, t) {
|
|
980
|
+
const s = `${o.replace(/\/$/, "")}/widget/install`, i = await fetch(s, {
|
|
939
981
|
method: "POST",
|
|
940
982
|
headers: { "Content-Type": "application/json", Origin: window.location.origin },
|
|
941
983
|
body: JSON.stringify({ token: e, organisationId: t })
|
|
@@ -943,19 +985,19 @@ async function ne(r, e, t) {
|
|
|
943
985
|
if (!i.ok) throw new Error(`SpilkiWidget: install failed (${i.status})`);
|
|
944
986
|
return (await i.json()).accessToken;
|
|
945
987
|
}
|
|
946
|
-
async function
|
|
947
|
-
const t = `${
|
|
988
|
+
async function he(o, e) {
|
|
989
|
+
const t = `${o.replace(/\/$/, "")}/widget/refresh`, s = await fetch(t, {
|
|
948
990
|
method: "POST",
|
|
949
991
|
headers: { "X-Authorization": `Bearer ${e}`, Origin: window.location.origin }
|
|
950
992
|
});
|
|
951
993
|
if (!s.ok) throw new Error(`SpilkiWidget: refresh failed (${s.status})`);
|
|
952
994
|
return (await s.json()).accessToken;
|
|
953
995
|
}
|
|
954
|
-
function
|
|
996
|
+
function de(o) {
|
|
955
997
|
let e = !1, t = null;
|
|
956
998
|
const s = [], i = () => {
|
|
957
999
|
var n;
|
|
958
|
-
if (!
|
|
1000
|
+
if (!o) return null;
|
|
959
1001
|
if (t) return t;
|
|
960
1002
|
try {
|
|
961
1003
|
const l = (n = window.AudioContext) != null ? n : window.webkitAudioContext;
|
|
@@ -965,7 +1007,7 @@ function le(r) {
|
|
|
965
1007
|
return null;
|
|
966
1008
|
}
|
|
967
1009
|
return t;
|
|
968
|
-
},
|
|
1010
|
+
}, r = () => {
|
|
969
1011
|
e = !0;
|
|
970
1012
|
try {
|
|
971
1013
|
const n = i();
|
|
@@ -975,23 +1017,23 @@ function le(r) {
|
|
|
975
1017
|
}
|
|
976
1018
|
}, a = (n) => {
|
|
977
1019
|
const l = () => {
|
|
978
|
-
|
|
1020
|
+
r(), window.removeEventListener(n, l, !0);
|
|
979
1021
|
};
|
|
980
1022
|
s.push({ type: n, listener: l }), window.addEventListener(n, l, { capture: !0, passive: !0 });
|
|
981
1023
|
};
|
|
982
1024
|
return a("pointerdown"), a("keydown"), {
|
|
983
|
-
markUserInteraction:
|
|
1025
|
+
markUserInteraction: r,
|
|
984
1026
|
play() {
|
|
985
|
-
if (!
|
|
1027
|
+
if (!o || !e) return;
|
|
986
1028
|
const n = i();
|
|
987
1029
|
if (!n || n.state !== "running") return;
|
|
988
1030
|
const l = n.createGain();
|
|
989
1031
|
l.gain.value = 0.15, l.connect(n.destination);
|
|
990
|
-
const g = (
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
},
|
|
994
|
-
g(880,
|
|
1032
|
+
const g = (h, d, m) => {
|
|
1033
|
+
const f = n.createOscillator(), p = n.createGain();
|
|
1034
|
+
f.type = "sine", f.frequency.setValueAtTime(h, d), p.gain.setValueAtTime(1e-4, d), p.gain.exponentialRampToValueAtTime(1, d + 0.012), p.gain.exponentialRampToValueAtTime(1e-4, d + m), f.connect(p), p.connect(l), f.start(d), f.stop(d + m + 0.02);
|
|
1035
|
+
}, u = n.currentTime;
|
|
1036
|
+
g(880, u, 0.08), g(1175, u + 0.09, 0.08);
|
|
995
1037
|
},
|
|
996
1038
|
destroy() {
|
|
997
1039
|
s.forEach(({ type: n, listener: l }) => {
|
|
@@ -1001,112 +1043,115 @@ function le(r) {
|
|
|
1001
1043
|
}
|
|
1002
1044
|
};
|
|
1003
1045
|
}
|
|
1004
|
-
function U(
|
|
1005
|
-
var O, M,
|
|
1006
|
-
if (!
|
|
1046
|
+
function U(o) {
|
|
1047
|
+
var I, O, M, B;
|
|
1048
|
+
if (!o.org)
|
|
1007
1049
|
throw new Error("SpilkiWidget: org is required");
|
|
1008
|
-
const e = H(
|
|
1009
|
-
|
|
1010
|
-
const t = { ...
|
|
1011
|
-
let
|
|
1050
|
+
const e = H(o);
|
|
1051
|
+
G(e.allowedOriginsHint);
|
|
1052
|
+
const t = { ...le, ...(I = e.hooks) != null ? I : {} }, s = new oe(e.org, { persist: e.persist }), i = de(e.sound);
|
|
1053
|
+
let r = (O = s.accessToken) != null ? O : void 0, a = null;
|
|
1012
1054
|
const n = () => {
|
|
1013
|
-
|
|
1055
|
+
u.setBadge(s.countUnread());
|
|
1014
1056
|
}, l = () => {
|
|
1015
|
-
s.markRead(),
|
|
1057
|
+
s.markRead(), u.setBadge(0);
|
|
1016
1058
|
}, g = async () => a || (a = (async () => {
|
|
1017
1059
|
try {
|
|
1018
|
-
if (
|
|
1060
|
+
if (r && ae(r))
|
|
1019
1061
|
try {
|
|
1020
|
-
|
|
1062
|
+
r = await he(e.apiBase, r), s.persistAccessToken(r), d.setAccessToken(r);
|
|
1021
1063
|
return;
|
|
1022
1064
|
} catch {
|
|
1023
|
-
|
|
1065
|
+
r = void 0, s.clearAccessToken();
|
|
1024
1066
|
}
|
|
1025
|
-
if (!
|
|
1026
|
-
if (!
|
|
1027
|
-
if (!
|
|
1028
|
-
|
|
1067
|
+
if (!r) {
|
|
1068
|
+
if (!o.installationToken) throw new Error("SpilkiWidget: missing installationToken");
|
|
1069
|
+
if (!o.org) throw new Error("SpilkiWidget: missing org");
|
|
1070
|
+
r = await ce(e.apiBase, o.installationToken, o.org), s.persistAccessToken(r), d.setAccessToken(r);
|
|
1029
1071
|
}
|
|
1030
1072
|
} finally {
|
|
1031
1073
|
a = null;
|
|
1032
1074
|
}
|
|
1033
|
-
})(), a),
|
|
1075
|
+
})(), a), u = R({
|
|
1034
1076
|
color: e.color,
|
|
1035
|
-
position: (
|
|
1077
|
+
position: (M = e.position) != null ? M : "bottom-right",
|
|
1036
1078
|
onClick: () => {
|
|
1037
1079
|
s.snapshot.isOpen ? (s.close(), t.onClose()) : (i.markUserInteraction(), s.open(), l(), t.onOpen());
|
|
1038
1080
|
}
|
|
1039
|
-
}),
|
|
1081
|
+
}), h = new Q({
|
|
1040
1082
|
color: e.color,
|
|
1041
|
-
theme:
|
|
1042
|
-
position: (
|
|
1083
|
+
theme: P(e.theme),
|
|
1084
|
+
position: (B = e.position) != null ? B : "bottom-right",
|
|
1043
1085
|
i18n: e.i18n,
|
|
1044
1086
|
onClose: () => {
|
|
1045
1087
|
s.close(), t.onClose();
|
|
1046
1088
|
},
|
|
1047
1089
|
onSend: (c) => {
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
t.onError(
|
|
1090
|
+
const k = s.addMessage({ author: "user", text: c });
|
|
1091
|
+
k && (h.appendMessage(k), g().then(() => d.send(c, k.id)).catch((b) => {
|
|
1092
|
+
t.onError(b), s.setConnected(!1), h.setOffline(!0);
|
|
1051
1093
|
}));
|
|
1052
1094
|
}
|
|
1053
|
-
}),
|
|
1095
|
+
}), d = new ee(
|
|
1054
1096
|
{
|
|
1055
1097
|
apiBase: e.apiBase,
|
|
1056
|
-
accessToken:
|
|
1098
|
+
accessToken: r,
|
|
1057
1099
|
org: e.org,
|
|
1058
1100
|
sessionId: s.sessionId
|
|
1059
1101
|
},
|
|
1060
1102
|
{
|
|
1061
1103
|
onOpen(c) {
|
|
1062
|
-
|
|
1104
|
+
A.transport = c, t.onTransportChange(c), s.setConnected(!0), h.setOffline(!1);
|
|
1063
1105
|
},
|
|
1064
1106
|
onMessage(c) {
|
|
1065
|
-
const
|
|
1066
|
-
|
|
1107
|
+
const b = c.suggestedReplies, y = s.addMessage(c);
|
|
1108
|
+
y && (h.appendMessage(y), y.author === "bot" && b && b.length > 0 && h.setSuggestedReplies(b), !s.snapshot.isOpen && y.author === "bot" && (n(), i.play()), t.onMessage(y));
|
|
1067
1109
|
},
|
|
1068
1110
|
onTyping(c) {
|
|
1069
1111
|
s.setTyping(c);
|
|
1070
1112
|
},
|
|
1113
|
+
onAgentEvent(c) {
|
|
1114
|
+
s.handleAgentEvent(c.eventType, c.active);
|
|
1115
|
+
},
|
|
1071
1116
|
onError(c) {
|
|
1072
|
-
t.onError(c), s.setConnected(!1), s.snapshot.isOpen &&
|
|
1117
|
+
t.onError(c), s.setConnected(!1), s.snapshot.isOpen && h.setOffline(!0);
|
|
1073
1118
|
}
|
|
1074
1119
|
}
|
|
1075
1120
|
);
|
|
1076
|
-
|
|
1077
|
-
const
|
|
1078
|
-
if (
|
|
1121
|
+
u.mount(), h.mount();
|
|
1122
|
+
const m = s.snapshot.messages, f = s.isSessionExpired(), p = s.getConversationGroups();
|
|
1123
|
+
if (m.length === 0 && e.welcome) {
|
|
1079
1124
|
const c = {
|
|
1080
1125
|
id: "welcome",
|
|
1081
1126
|
author: "bot",
|
|
1082
1127
|
text: e.welcome,
|
|
1083
1128
|
ts: Date.now()
|
|
1084
1129
|
};
|
|
1085
|
-
s.addMessage(c),
|
|
1086
|
-
} else
|
|
1087
|
-
let
|
|
1088
|
-
const
|
|
1130
|
+
s.addMessage(c), h.appendMessage(c);
|
|
1131
|
+
} else f && m.length > 0 ? h.renderWithConversations(p, []) : p.length > 1 ? h.renderWithConversations(p.slice(0, -1), p[p.length - 1].messages) : h.updateMessages(m);
|
|
1132
|
+
let S = !1;
|
|
1133
|
+
const $ = s.subscribe(() => {
|
|
1089
1134
|
const c = s.snapshot;
|
|
1090
|
-
if (
|
|
1091
|
-
if (!
|
|
1092
|
-
const
|
|
1093
|
-
l(),
|
|
1135
|
+
if (u.setOpen(c.isOpen), h.setAgentActivity(c.agentActivity, e.i18n), h.setOffline(!c.isConnected), h.updateTheme(P(e.theme)), c.isOpen) {
|
|
1136
|
+
if (!S) {
|
|
1137
|
+
const k = s.countUnread() > 0, b = s.lastReadTs;
|
|
1138
|
+
l(), k && h.scrollToFirstUnread(b);
|
|
1094
1139
|
}
|
|
1095
|
-
|
|
1140
|
+
S = !0, h.show();
|
|
1096
1141
|
} else
|
|
1097
|
-
|
|
1098
|
-
}),
|
|
1142
|
+
S = !1, h.hide();
|
|
1143
|
+
}), W = m.length === 0 || f;
|
|
1099
1144
|
n(), g().then(
|
|
1100
|
-
() =>
|
|
1101
|
-
var
|
|
1102
|
-
e.persist && s.persistSession(c.sessionId), s.setConnected(!0), t.onTransportChange((
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1145
|
+
() => d.connect().then((c) => {
|
|
1146
|
+
var b, y;
|
|
1147
|
+
e.persist && s.persistSession(c.sessionId), s.setConnected(!0), t.onTransportChange((b = d.kind) != null ? b : "ws");
|
|
1148
|
+
const k = (y = c.suggestedReplies) != null ? y : [];
|
|
1149
|
+
k.length > 0 && W && h.setSuggestedReplies(k);
|
|
1105
1150
|
})
|
|
1106
1151
|
).catch((c) => {
|
|
1107
|
-
t.onError(c), s.setConnected(!1),
|
|
1152
|
+
t.onError(c), s.setConnected(!1), h.setOffline(!0);
|
|
1108
1153
|
});
|
|
1109
|
-
const
|
|
1154
|
+
const A = {
|
|
1110
1155
|
transport: null,
|
|
1111
1156
|
open() {
|
|
1112
1157
|
i.markUserInteraction(), s.open(), l(), t.onOpen();
|
|
@@ -1115,17 +1160,17 @@ function U(r) {
|
|
|
1115
1160
|
s.close(), t.onClose();
|
|
1116
1161
|
},
|
|
1117
1162
|
destroy() {
|
|
1118
|
-
|
|
1163
|
+
$(), d.stop(), i.destroy(), u.destroy(), h.destroy();
|
|
1119
1164
|
}
|
|
1120
1165
|
};
|
|
1121
|
-
return
|
|
1166
|
+
return A;
|
|
1122
1167
|
}
|
|
1123
|
-
function
|
|
1168
|
+
function N() {
|
|
1124
1169
|
var s, i;
|
|
1125
1170
|
if (typeof document == "undefined") return;
|
|
1126
|
-
const
|
|
1127
|
-
if (!
|
|
1128
|
-
const e =
|
|
1171
|
+
const o = document.currentScript;
|
|
1172
|
+
if (!o) return;
|
|
1173
|
+
const e = o.dataset;
|
|
1129
1174
|
if (e.autoinit === "false") return;
|
|
1130
1175
|
const t = e.org;
|
|
1131
1176
|
if (!t) {
|
|
@@ -1140,7 +1185,7 @@ function $() {
|
|
|
1140
1185
|
theme: (i = e.theme) != null ? i : void 0
|
|
1141
1186
|
});
|
|
1142
1187
|
}
|
|
1143
|
-
typeof window != "undefined" && (window.SpilkiWidget = window.SpilkiWidget || {}, window.SpilkiWidget.init = (
|
|
1144
|
-
|
|
1145
|
-
|
|
1188
|
+
typeof window != "undefined" && (window.SpilkiWidget = window.SpilkiWidget || {}, window.SpilkiWidget.init = (o) => U(o));
|
|
1189
|
+
N();
|
|
1190
|
+
N();
|
|
1146
1191
|
//# sourceMappingURL=bootstrap.es.js.map
|