@spilki/widget 0.1.1 → 0.1.3
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 +68 -67
- package/dist/bootstrap.es.js.map +1 -1
- package/dist/bootstrap.umd.js +3 -3
- package/dist/bootstrap.umd.js.map +1 -1
- package/dist/core/state.d.ts +1 -2
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/transport.d.ts +1 -1
- 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 +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/widget.es.js +72 -71
- 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/README.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@spilki/widget)
|
|
4
4
|
[](#size-budget)
|
|
5
5
|
|
|
6
|
-
Embeddable chat widget that connects your website visitors with the Spilki assistant backend via a secure Web Widget
|
|
6
|
+
Embeddable chat widget that connects your website visitors with the Spilki assistant backend via a secure Web Widget
|
|
7
|
+
channel.
|
|
7
8
|
|
|
8
9
|
## Features
|
|
9
10
|
|
|
@@ -24,40 +25,38 @@ npm install @spilki/widget
|
|
|
24
25
|
### CDN (UMD)
|
|
25
26
|
|
|
26
27
|
```html
|
|
28
|
+
|
|
27
29
|
<script src="https://cdn.jsdelivr.net/npm/@spilki/widget/dist/widget.umd.js"
|
|
28
30
|
data-org="ori-bar"
|
|
29
|
-
data-assistant="main-bot"
|
|
30
31
|
data-token="<your-jwt>"></script>
|
|
31
32
|
```
|
|
32
33
|
|
|
33
34
|
### ESM
|
|
34
35
|
|
|
35
36
|
```ts
|
|
36
|
-
import {
|
|
37
|
+
import {initSpilkiWidget} from "@spilki/widget";
|
|
37
38
|
|
|
38
39
|
initSpilkiWidget({
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
token: "<your-jwt>"
|
|
40
|
+
org: "ori-bar",
|
|
41
|
+
token: "<your-jwt>"
|
|
42
42
|
});
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
## Options
|
|
46
46
|
|
|
47
|
-
| Option
|
|
48
|
-
|
|
49
|
-
| `org`
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `hooks` | `Partial<WidgetHooks>?` | – | Telemetry callbacks for open/close/message/error/transport change. |
|
|
47
|
+
| Option | Type | Default | Description |
|
|
48
|
+
|----------------------|-----------------------------------|---------------------------|-----------------------------------------------------------------------------------------|
|
|
49
|
+
| `org` | `string` | – | Spilki organisation identifier. |
|
|
50
|
+
| `token` | `string?` | – | Signed JWT obtained from the admin UI or backend. |
|
|
51
|
+
| `apiBase` | `string?` | `https://api.spilki.ai` | Override API endpoint (useful for staging/local). |
|
|
52
|
+
| `position` | `"bottom-right" \| "bottom-left"` | `"bottom-right"` | Corner to anchor the bubble + panel. |
|
|
53
|
+
| `theme` | `"auto" \| "light" \| "dark"` | `"auto"` | Force light/dark or respect OS preference. |
|
|
54
|
+
| `color` | `string?` | `#6366f1` | Accent color for bubble + primary CTA. |
|
|
55
|
+
| `welcome` | `string?` | "Hi! I'm your assistant." | Greeting shown when no conversation exists. |
|
|
56
|
+
| `persist` | `boolean?` | `true` | Persist session + history in localStorage. |
|
|
57
|
+
| `allowedOriginsHint` | `string[]?` | – | List of origins expected to be in JWT allowlist. Logs warnings during misconfiguration. |
|
|
58
|
+
| `i18n` | `Partial<WidgetI18n>?` | – | Override UI strings (welcome, placeholder, sendLabel, typing, offline, title). |
|
|
59
|
+
| `hooks` | `Partial<WidgetHooks>?` | – | Telemetry callbacks for open/close/message/error/transport change. |
|
|
61
60
|
|
|
62
61
|
## Security
|
|
63
62
|
|
|
@@ -66,13 +65,16 @@ The widget never stores credentials. Provide a short-lived JWT (HS256) issued se
|
|
|
66
65
|
```json
|
|
67
66
|
{
|
|
68
67
|
"organisation_id": "ori-bar",
|
|
69
|
-
"
|
|
70
|
-
|
|
68
|
+
"allowed_origins": [
|
|
69
|
+
"https://yourdomain.com"
|
|
70
|
+
],
|
|
71
71
|
"exp": 1760000000
|
|
72
72
|
}
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
During `POST /widget/
|
|
75
|
+
During `POST /widget/session` the widget sends `Origin` and the JWT for verification. Expired tokens are rejected
|
|
76
|
+
client-side before any network call. Rotate tokens frequently and limit the allowed origins array to trusted domains
|
|
77
|
+
only.
|
|
76
78
|
|
|
77
79
|
See [`apps/mock-server/openapi.yaml`](../apps/mock-server/openapi.yaml) for the full handshake specification.
|
|
78
80
|
|
|
@@ -92,8 +94,10 @@ pnpm install
|
|
|
92
94
|
pnpm -w dev # runs mock server + demo site
|
|
93
95
|
```
|
|
94
96
|
|
|
95
|
-
Open [http://localhost:5174](http://localhost:5174) and use **Issue token** to obtain a development JWT. Messages are
|
|
97
|
+
Open [http://localhost:5174](http://localhost:5174) and use **Issue token** to obtain a development JWT. Messages are
|
|
98
|
+
relayed via websocket by default; stop the websocket server to see SSE fallback.
|
|
96
99
|
|
|
97
100
|
## Publishing
|
|
98
101
|
|
|
99
|
-
The GitHub Actions workflow publishes on tags that match `v*`. Ensure `NPM_TOKEN` is configured in the repository
|
|
102
|
+
The GitHub Actions workflow publishes on tags that match `v*`. Ensure `NPM_TOKEN` is configured in the repository
|
|
103
|
+
secrets before tagging `v0.1.3` or later.
|
package/dist/bootstrap.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const A = `
|
|
2
2
|
<style>
|
|
3
3
|
:host {
|
|
4
4
|
all: initial;
|
|
@@ -44,11 +44,11 @@ const M = `
|
|
|
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 = A;
|
|
52
52
|
const s = t.querySelector("button");
|
|
53
53
|
return s.addEventListener("click", () => r.onClick()), {
|
|
54
54
|
element: e,
|
|
@@ -58,16 +58,16 @@ function A(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 C = ':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 W {
|
|
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>${C}</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,7 +149,7 @@ class C {
|
|
|
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 $ = "https://api.spilki.ai", g = {
|
|
153
153
|
welcome: "Hi! I'm your assistant.",
|
|
154
154
|
placeholder: "Type a message…",
|
|
155
155
|
sendLabel: "Send",
|
|
@@ -157,7 +157,7 @@ const W = "https://api.spilki.ai", g = {
|
|
|
157
157
|
offline: "Unable to connect. Please try again later.",
|
|
158
158
|
title: "Spilki Assistant"
|
|
159
159
|
}, p = {
|
|
160
|
-
apiBase:
|
|
160
|
+
apiBase: $,
|
|
161
161
|
position: "bottom-right",
|
|
162
162
|
theme: "auto",
|
|
163
163
|
color: "#6366f1",
|
|
@@ -166,7 +166,7 @@ const W = "https://api.spilki.ai", g = {
|
|
|
166
166
|
i18n: g
|
|
167
167
|
};
|
|
168
168
|
function B(r) {
|
|
169
|
-
var t, s, i,
|
|
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,
|
|
@@ -174,7 +174,7 @@ function B(r) {
|
|
|
174
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: (
|
|
177
|
+
position: (n = r.position) != null ? n : p.position,
|
|
178
178
|
theme: (l = r.theme) != null ? l : p.theme,
|
|
179
179
|
color: (a = r.color) != null ? a : p.color,
|
|
180
180
|
persist: (h = r.persist) != null ? h : p.persist
|
|
@@ -205,6 +205,9 @@ class U {
|
|
|
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
|
}
|
|
208
|
+
setAccessToken(e) {
|
|
209
|
+
this.options.accessToken = e;
|
|
210
|
+
}
|
|
208
211
|
get kind() {
|
|
209
212
|
return this.currentKind;
|
|
210
213
|
}
|
|
@@ -215,9 +218,8 @@ class U {
|
|
|
215
218
|
async connect() {
|
|
216
219
|
var l, a;
|
|
217
220
|
this.stopped = !1;
|
|
218
|
-
const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/
|
|
221
|
+
const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/session`, t = (a = (l = this.sessionId) != null ? l : this.options.sessionId) != null ? a : void 0, s = {
|
|
219
222
|
organisationId: this.options.org,
|
|
220
|
-
assistantId: this.options.assistant,
|
|
221
223
|
sessionId: t,
|
|
222
224
|
userAgent: typeof navigator != "undefined" ? navigator.userAgent : "",
|
|
223
225
|
referrer: typeof document != "undefined" ? document.referrer : "",
|
|
@@ -232,13 +234,13 @@ class U {
|
|
|
232
234
|
});
|
|
233
235
|
if (!i.ok)
|
|
234
236
|
throw new Error(`SpilkiWidget: connect failed (${i.status})`);
|
|
235
|
-
const
|
|
236
|
-
return this.sessionId =
|
|
237
|
+
const n = await i.json();
|
|
238
|
+
return this.sessionId = n.sessionId, this.options.sessionId = n.sessionId, this.backoff = d, await this.startTransport(n), n;
|
|
237
239
|
}
|
|
238
240
|
async send(e) {
|
|
239
|
-
var
|
|
241
|
+
var n, l;
|
|
240
242
|
const t = {
|
|
241
|
-
sessionId: (l = (
|
|
243
|
+
sessionId: (l = (n = this.sessionId) != null ? n : this.options.sessionId) != null ? l : "",
|
|
242
244
|
text: e
|
|
243
245
|
};
|
|
244
246
|
if (!t.sessionId)
|
|
@@ -284,7 +286,7 @@ class U {
|
|
|
284
286
|
return;
|
|
285
287
|
}
|
|
286
288
|
this.currentKind = "ws", this.handlers.onOpen("ws"), this.backoff = d, t();
|
|
287
|
-
}), i.addEventListener("message", (
|
|
289
|
+
}), i.addEventListener("message", (n) => this.handleIncoming(n.data)), i.addEventListener("close", () => {
|
|
288
290
|
this.stopped || this.retryFallback("ws");
|
|
289
291
|
}), i.addEventListener("error", () => {
|
|
290
292
|
this.handlers.onError(new Error("SpilkiWidget: websocket error")), i.readyState !== WebSocket.OPEN && s(new Error("WebSocket failed"));
|
|
@@ -302,15 +304,15 @@ class U {
|
|
|
302
304
|
}
|
|
303
305
|
const i = new EventSource(e);
|
|
304
306
|
this.sse = i;
|
|
305
|
-
let
|
|
307
|
+
let n = !1;
|
|
306
308
|
i.addEventListener("open", () => {
|
|
307
|
-
if (
|
|
309
|
+
if (n = !0, this.stopped) {
|
|
308
310
|
i.close();
|
|
309
311
|
return;
|
|
310
312
|
}
|
|
311
313
|
this.currentKind = "sse", this.handlers.onOpen("sse"), this.backoff = d, t();
|
|
312
314
|
}), i.addEventListener("message", (l) => this.handleIncoming(l.data)), i.addEventListener("error", () => {
|
|
313
|
-
if (!
|
|
315
|
+
if (!n) {
|
|
314
316
|
s(new Error("SSE failed"));
|
|
315
317
|
return;
|
|
316
318
|
}
|
|
@@ -326,7 +328,7 @@ class U {
|
|
|
326
328
|
const s = await fetch(e);
|
|
327
329
|
if (!s.ok) throw new Error(`Poll failed ${s.status}`);
|
|
328
330
|
const i = await s.json();
|
|
329
|
-
u(i).forEach((
|
|
331
|
+
u(i).forEach((n) => this.handlers.onMessage(n)), this.backoff = d;
|
|
330
332
|
} catch (s) {
|
|
331
333
|
this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5, v);
|
|
332
334
|
} finally {
|
|
@@ -369,13 +371,13 @@ class U {
|
|
|
369
371
|
}
|
|
370
372
|
const f = 30;
|
|
371
373
|
class N {
|
|
372
|
-
constructor(e, t
|
|
373
|
-
this.org = e, this.
|
|
374
|
+
constructor(e, t) {
|
|
375
|
+
this.org = e, this.listeners = /* @__PURE__ */ new Set(), this.state = {
|
|
374
376
|
isOpen: !1,
|
|
375
377
|
isTyping: !1,
|
|
376
378
|
isConnected: !1,
|
|
377
379
|
messages: []
|
|
378
|
-
}, this.historyKey = `spilki-history:${e}
|
|
380
|
+
}, 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
381
|
}
|
|
380
382
|
get snapshot() {
|
|
381
383
|
return { ...this.state, messages: [...this.state.messages] };
|
|
@@ -522,14 +524,14 @@ const H = {
|
|
|
522
524
|
onTransportChange() {
|
|
523
525
|
}
|
|
524
526
|
};
|
|
525
|
-
async function q(r, e) {
|
|
526
|
-
const
|
|
527
|
+
async function q(r, e, t) {
|
|
528
|
+
const s = `${r.replace(/\/$/, "")}/widget/install`, i = await fetch(s, {
|
|
527
529
|
method: "POST",
|
|
528
530
|
headers: { "Content-Type": "application/json", Origin: window.location.origin },
|
|
529
|
-
body: JSON.stringify({ token: e })
|
|
531
|
+
body: JSON.stringify({ token: e, organisationId: t })
|
|
530
532
|
});
|
|
531
|
-
if (!
|
|
532
|
-
return (await
|
|
533
|
+
if (!i.ok) throw new Error(`SpilkiWidget: install failed (${i.status})`);
|
|
534
|
+
return (await i.json()).accessToken;
|
|
533
535
|
}
|
|
534
536
|
async function J(r, e) {
|
|
535
537
|
const t = `${r.replace(/\/$/, "")}/widget/refresh`, s = await fetch(t, {
|
|
@@ -541,26 +543,27 @@ async function J(r, e) {
|
|
|
541
543
|
}
|
|
542
544
|
function E(r) {
|
|
543
545
|
var k, w, y, S;
|
|
544
|
-
if (!r.org
|
|
545
|
-
throw new Error("SpilkiWidget: org
|
|
546
|
+
if (!r.org)
|
|
547
|
+
throw new Error("SpilkiWidget: org is required");
|
|
546
548
|
const e = B(r);
|
|
547
549
|
P(e.allowedOriginsHint);
|
|
548
|
-
const t = { ...H, ...(k = e.hooks) != null ? k : {} }, s = new N(e.org,
|
|
550
|
+
const t = { ...H, ...(k = e.hooks) != null ? k : {} }, s = new N(e.org, { persist: e.persist });
|
|
549
551
|
let i = (w = s.accessToken) != null ? w : void 0;
|
|
550
|
-
const
|
|
552
|
+
const n = async () => {
|
|
551
553
|
if (!i) {
|
|
552
554
|
if (!r.installationToken) throw new Error("SpilkiWidget: missing installationToken");
|
|
553
|
-
|
|
555
|
+
if (!r.org) throw new Error("SpilkiWidget: missing org");
|
|
556
|
+
i = await q(e.apiBase, r.installationToken, r.org), s.persistAccessToken(i), h.setAccessToken(i);
|
|
554
557
|
return;
|
|
555
558
|
}
|
|
556
|
-
z(i) && (i = await J(e.apiBase, i), s.persistAccessToken(i));
|
|
557
|
-
}, l =
|
|
559
|
+
z(i) && (i = await J(e.apiBase, i), s.persistAccessToken(i), h.setAccessToken(i));
|
|
560
|
+
}, l = M({
|
|
558
561
|
color: e.color,
|
|
559
562
|
position: (y = e.position) != null ? y : "bottom-right",
|
|
560
563
|
onClick: () => {
|
|
561
564
|
s.snapshot.isOpen ? (s.close(), t.onClose()) : (s.open(), t.onOpen());
|
|
562
565
|
}
|
|
563
|
-
}), a = new
|
|
566
|
+
}), a = new W({
|
|
564
567
|
color: e.color,
|
|
565
568
|
theme: x(e.theme),
|
|
566
569
|
position: (S = e.position) != null ? S : "bottom-right",
|
|
@@ -568,9 +571,9 @@ function E(r) {
|
|
|
568
571
|
onClose: () => {
|
|
569
572
|
s.close(), t.onClose();
|
|
570
573
|
},
|
|
571
|
-
onSend: (
|
|
572
|
-
const c = s.addMessage({ author: "user", text:
|
|
573
|
-
a.appendMessage(c),
|
|
574
|
+
onSend: (o) => {
|
|
575
|
+
const c = s.addMessage({ author: "user", text: o });
|
|
576
|
+
a.appendMessage(c), n().then(() => h.send(o)).catch((O) => {
|
|
574
577
|
t.onError(O), s.setConnected(!1), a.setOffline(!0);
|
|
575
578
|
});
|
|
576
579
|
}
|
|
@@ -579,48 +582,47 @@ function E(r) {
|
|
|
579
582
|
apiBase: e.apiBase,
|
|
580
583
|
accessToken: i,
|
|
581
584
|
org: e.org,
|
|
582
|
-
assistant: e.assistant,
|
|
583
585
|
sessionId: s.sessionId
|
|
584
586
|
},
|
|
585
587
|
{
|
|
586
|
-
onOpen(
|
|
587
|
-
m.transport =
|
|
588
|
+
onOpen(o) {
|
|
589
|
+
m.transport = o, t.onTransportChange(o), s.setConnected(!0), a.setOffline(!1);
|
|
588
590
|
},
|
|
589
|
-
onMessage(
|
|
590
|
-
const c = s.addMessage(
|
|
591
|
+
onMessage(o) {
|
|
592
|
+
const c = s.addMessage(o);
|
|
591
593
|
a.appendMessage(c), t.onMessage(c);
|
|
592
594
|
},
|
|
593
|
-
onTyping(
|
|
594
|
-
s.setTyping(
|
|
595
|
+
onTyping(o) {
|
|
596
|
+
s.setTyping(o);
|
|
595
597
|
},
|
|
596
|
-
onError(
|
|
597
|
-
t.onError(
|
|
598
|
+
onError(o) {
|
|
599
|
+
t.onError(o), s.setConnected(!1), s.snapshot.isOpen && a.setOffline(!0);
|
|
598
600
|
}
|
|
599
601
|
}
|
|
600
602
|
);
|
|
601
603
|
l.mount(), a.mount();
|
|
602
604
|
const b = s.snapshot.messages;
|
|
603
605
|
if (b.length === 0 && e.welcome) {
|
|
604
|
-
const
|
|
606
|
+
const o = {
|
|
605
607
|
id: "welcome",
|
|
606
608
|
author: "bot",
|
|
607
609
|
text: e.welcome,
|
|
608
610
|
ts: Date.now()
|
|
609
611
|
};
|
|
610
|
-
s.addMessage(
|
|
612
|
+
s.addMessage(o), a.appendMessage(o);
|
|
611
613
|
} else
|
|
612
614
|
a.updateMessages(b);
|
|
613
615
|
const I = s.subscribe(() => {
|
|
614
|
-
const
|
|
615
|
-
l.setOpen(
|
|
616
|
+
const o = s.snapshot;
|
|
617
|
+
l.setOpen(o.isOpen), a.setTyping(o.isTyping), a.setOffline(!o.isConnected), a.updateTheme(x(e.theme)), o.isOpen ? a.show() : a.hide();
|
|
616
618
|
});
|
|
617
|
-
|
|
618
|
-
() => h.connect().then((
|
|
619
|
+
n().then(
|
|
620
|
+
() => h.connect().then((o) => {
|
|
619
621
|
var c;
|
|
620
|
-
e.persist && s.persistSession(
|
|
622
|
+
e.persist && s.persistSession(o.sessionId), s.setConnected(!0), t.onTransportChange((c = h.kind) != null ? c : "ws");
|
|
621
623
|
})
|
|
622
|
-
).catch((
|
|
623
|
-
t.onError(
|
|
624
|
+
).catch((o) => {
|
|
625
|
+
t.onError(o), s.setConnected(!1), a.setOffline(!0);
|
|
624
626
|
});
|
|
625
627
|
const m = {
|
|
626
628
|
transport: null,
|
|
@@ -637,24 +639,23 @@ function E(r) {
|
|
|
637
639
|
return m;
|
|
638
640
|
}
|
|
639
641
|
function T() {
|
|
640
|
-
var
|
|
642
|
+
var s, i;
|
|
641
643
|
if (typeof document == "undefined") return;
|
|
642
644
|
const r = document.currentScript;
|
|
643
645
|
if (!r) return;
|
|
644
646
|
const e = r.dataset;
|
|
645
647
|
if (e.autoinit === "false") return;
|
|
646
|
-
const t = e.org
|
|
647
|
-
if (!t
|
|
648
|
-
console.error("SpilkiWidget: data-org and
|
|
648
|
+
const t = e.org;
|
|
649
|
+
if (!t) {
|
|
650
|
+
console.error("SpilkiWidget: data-org and is required for auto init");
|
|
649
651
|
return;
|
|
650
652
|
}
|
|
651
653
|
E({
|
|
652
654
|
org: t,
|
|
653
|
-
assistant: s,
|
|
654
655
|
installationToken: e.installationToken,
|
|
655
656
|
apiBase: e.apiBase,
|
|
656
|
-
position: (
|
|
657
|
-
theme: (
|
|
657
|
+
position: (s = e.position) != null ? s : void 0,
|
|
658
|
+
theme: (i = e.theme) != null ? i : void 0
|
|
658
659
|
});
|
|
659
660
|
}
|
|
660
661
|
if (typeof window != "undefined") {
|