@spilki/widget 0.1.1 → 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 CHANGED
@@ -3,7 +3,8 @@
3
3
  [![npm version](https://img.shields.io/npm/v/%40spilki/widget.svg)](https://www.npmjs.com/package/@spilki/widget)
4
4
  [![bundle size](https://img.shields.io/badge/gzip%20%3C=35kB-success)](#size-budget)
5
5
 
6
- Embeddable chat widget that connects your website visitors with the Spilki assistant backend via a secure Web Widget channel.
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 { initSpilkiWidget } from "@spilki/widget";
37
+ import {initSpilkiWidget} from "@spilki/widget";
37
38
 
38
39
  initSpilkiWidget({
39
- org: "ori-bar",
40
- assistant: "main-bot",
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 | Type | Default | Description |
48
- | --- | --- | --- | --- |
49
- | `org` | `string` | – | Spilki organisation identifier. |
50
- | `assistant` | `string` | – | Assistant identifier. |
51
- | `token` | `string?` | | Signed JWT obtained from the admin UI or backend. |
52
- | `apiBase` | `string?` | `https://api.spilki.ai` | Override API endpoint (useful for staging/local). |
53
- | `position` | `"bottom-right" \| "bottom-left"` | `"bottom-right"` | Corner to anchor the bubble + panel. |
54
- | `theme` | `"auto" \| "light" \| "dark"` | `"auto"` | Force light/dark or respect OS preference. |
55
- | `color` | `string?` | `#6366f1` | Accent color for bubble + primary CTA. |
56
- | `welcome` | `string?` | "Hi! I'm your assistant." | Greeting shown when no conversation exists. |
57
- | `persist` | `boolean?` | `true` | Persist session + history in localStorage. |
58
- | `allowedOriginsHint` | `string[]?` | – | List of origins expected to be in JWT allowlist. Logs warnings during misconfiguration. |
59
- | `i18n` | `Partial<WidgetI18n>?` | – | Override UI strings (welcome, placeholder, sendLabel, typing, offline, title). |
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
- "assistant_id": "main-bot",
70
- "allowed_origins": ["https://yourdomain.com"],
68
+ "allowed_origins": [
69
+ "https://yourdomain.com"
70
+ ],
71
71
  "exp": 1760000000
72
72
  }
73
73
  ```
74
74
 
75
- During `POST /widget/connect` the widget sends `Origin` and the JWT for verification. Expired tokens are rejected client-side before any network call. Rotate tokens frequently and limit the allowed origins array to trusted domains only.
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 relayed via websocket by default; stop the websocket server to see SSE fallback.
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 secrets before tagging `v0.1.1` or later.
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.2` or later.
@@ -58,16 +58,16 @@ function A(r) {
58
58
  destroy() {
59
59
  e.remove();
60
60
  },
61
- setOpen(o) {
62
- s.setAttribute("aria-expanded", String(o));
61
+ setOpen(n) {
62
+ s.setAttribute("aria-expanded", String(n));
63
63
  }
64
64
  };
65
65
  }
66
- const $ = ':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 {
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>${$}</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 W = "https://api.spilki.ai", g = {
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: W,
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, o, l, a, h;
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: (o = r.position) != null ? o : p.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
@@ -215,9 +215,8 @@ class U {
215
215
  async connect() {
216
216
  var l, a;
217
217
  this.stopped = !1;
218
- const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/connect`, t = (a = (l = this.sessionId) != null ? l : this.options.sessionId) != null ? a : void 0, s = {
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 : "",
@@ -232,13 +231,13 @@ class U {
232
231
  });
233
232
  if (!i.ok)
234
233
  throw new Error(`SpilkiWidget: connect failed (${i.status})`);
235
- const o = await i.json();
236
- return this.sessionId = o.sessionId, this.options.sessionId = o.sessionId, this.backoff = d, await this.startTransport(o), o;
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 o, l;
238
+ var n, l;
240
239
  const t = {
241
- sessionId: (l = (o = this.sessionId) != null ? o : this.options.sessionId) != null ? l : "",
240
+ sessionId: (l = (n = this.sessionId) != null ? n : this.options.sessionId) != null ? l : "",
242
241
  text: e
243
242
  };
244
243
  if (!t.sessionId)
@@ -284,7 +283,7 @@ class U {
284
283
  return;
285
284
  }
286
285
  this.currentKind = "ws", this.handlers.onOpen("ws"), this.backoff = d, t();
287
- }), i.addEventListener("message", (o) => this.handleIncoming(o.data)), i.addEventListener("close", () => {
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 U {
302
301
  }
303
302
  const i = new EventSource(e);
304
303
  this.sse = i;
305
- let o = !1;
304
+ let n = !1;
306
305
  i.addEventListener("open", () => {
307
- if (o = !0, this.stopped) {
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
311
  }), i.addEventListener("message", (l) => this.handleIncoming(l.data)), i.addEventListener("error", () => {
313
- if (!o) {
312
+ if (!n) {
314
313
  s(new Error("SSE failed"));
315
314
  return;
316
315
  }
@@ -326,7 +325,7 @@ class U {
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((o) => this.handlers.onMessage(o)), this.backoff = d;
328
+ u(i).forEach((n) => this.handlers.onMessage(n)), this.backoff = d;
330
329
  } catch (s) {
331
330
  this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5, v);
332
331
  } finally {
@@ -369,13 +368,13 @@ class U {
369
368
  }
370
369
  const f = 30;
371
370
  class N {
372
- constructor(e, t, s) {
373
- this.org = e, this.assistant = t, this.listeners = /* @__PURE__ */ new Set(), this.state = {
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}:${t}`, this.sessionKey = `spilki-session:${e}:${t}`, this.tokenKey = `spilki-token:${e}:${t}`, this.persist = s.persist, this.state.messages = this.loadMessages();
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] };
@@ -522,14 +521,14 @@ const H = {
522
521
  onTransportChange() {
523
522
  }
524
523
  };
525
- async function q(r, e) {
526
- const t = `${r.replace(/\/$/, "")}/widget/install`, s = await fetch(t, {
524
+ async function q(r, e, t) {
525
+ const s = `${r.replace(/\/$/, "")}/widget/install`, i = await fetch(s, {
527
526
  method: "POST",
528
527
  headers: { "Content-Type": "application/json", Origin: window.location.origin },
529
- body: JSON.stringify({ token: e })
528
+ body: JSON.stringify({ token: e, organisationId: t })
530
529
  });
531
- if (!s.ok) throw new Error(`SpilkiWidget: install failed (${s.status})`);
532
- return (await s.json()).accessToken;
530
+ if (!i.ok) throw new Error(`SpilkiWidget: install failed (${i.status})`);
531
+ return (await i.json()).accessToken;
533
532
  }
534
533
  async function J(r, e) {
535
534
  const t = `${r.replace(/\/$/, "")}/widget/refresh`, s = await fetch(t, {
@@ -541,16 +540,17 @@ async function J(r, e) {
541
540
  }
542
541
  function E(r) {
543
542
  var k, w, y, S;
544
- if (!r.org || !r.assistant)
545
- throw new Error("SpilkiWidget: org and assistant are required");
543
+ if (!r.org)
544
+ throw new Error("SpilkiWidget: org is required");
546
545
  const e = B(r);
547
546
  P(e.allowedOriginsHint);
548
- const t = { ...H, ...(k = e.hooks) != null ? k : {} }, s = new N(e.org, e.assistant, { persist: e.persist });
547
+ const t = { ...H, ...(k = e.hooks) != null ? k : {} }, s = new N(e.org, { persist: e.persist });
549
548
  let i = (w = s.accessToken) != null ? w : void 0;
550
- const o = async () => {
549
+ const n = async () => {
551
550
  if (!i) {
552
551
  if (!r.installationToken) throw new Error("SpilkiWidget: missing installationToken");
553
- i = await q(e.apiBase, r.installationToken), s.persistAccessToken(i);
552
+ if (!r.org) throw new Error("SpilkiWidget: missing org");
553
+ i = await q(e.apiBase, r.installationToken, r.org), s.persistAccessToken(i);
554
554
  return;
555
555
  }
556
556
  z(i) && (i = await J(e.apiBase, i), s.persistAccessToken(i));
@@ -560,7 +560,7 @@ function E(r) {
560
560
  onClick: () => {
561
561
  s.snapshot.isOpen ? (s.close(), t.onClose()) : (s.open(), t.onOpen());
562
562
  }
563
- }), a = new C({
563
+ }), a = new W({
564
564
  color: e.color,
565
565
  theme: x(e.theme),
566
566
  position: (S = e.position) != null ? S : "bottom-right",
@@ -568,9 +568,9 @@ function E(r) {
568
568
  onClose: () => {
569
569
  s.close(), t.onClose();
570
570
  },
571
- onSend: (n) => {
572
- const c = s.addMessage({ author: "user", text: n });
573
- a.appendMessage(c), o().then(() => h.send(n)).catch((O) => {
571
+ onSend: (o) => {
572
+ const c = s.addMessage({ author: "user", text: o });
573
+ a.appendMessage(c), n().then(() => h.send(o)).catch((O) => {
574
574
  t.onError(O), s.setConnected(!1), a.setOffline(!0);
575
575
  });
576
576
  }
@@ -579,48 +579,47 @@ function E(r) {
579
579
  apiBase: e.apiBase,
580
580
  accessToken: i,
581
581
  org: e.org,
582
- assistant: e.assistant,
583
582
  sessionId: s.sessionId
584
583
  },
585
584
  {
586
- onOpen(n) {
587
- m.transport = n, t.onTransportChange(n), s.setConnected(!0), a.setOffline(!1);
585
+ onOpen(o) {
586
+ m.transport = o, t.onTransportChange(o), s.setConnected(!0), a.setOffline(!1);
588
587
  },
589
- onMessage(n) {
590
- const c = s.addMessage(n);
588
+ onMessage(o) {
589
+ const c = s.addMessage(o);
591
590
  a.appendMessage(c), t.onMessage(c);
592
591
  },
593
- onTyping(n) {
594
- s.setTyping(n);
592
+ onTyping(o) {
593
+ s.setTyping(o);
595
594
  },
596
- onError(n) {
597
- t.onError(n), s.setConnected(!1), s.snapshot.isOpen && a.setOffline(!0);
595
+ onError(o) {
596
+ t.onError(o), s.setConnected(!1), s.snapshot.isOpen && a.setOffline(!0);
598
597
  }
599
598
  }
600
599
  );
601
600
  l.mount(), a.mount();
602
601
  const b = s.snapshot.messages;
603
602
  if (b.length === 0 && e.welcome) {
604
- const n = {
603
+ const o = {
605
604
  id: "welcome",
606
605
  author: "bot",
607
606
  text: e.welcome,
608
607
  ts: Date.now()
609
608
  };
610
- s.addMessage(n), a.appendMessage(n);
609
+ s.addMessage(o), a.appendMessage(o);
611
610
  } else
612
611
  a.updateMessages(b);
613
612
  const I = s.subscribe(() => {
614
- const n = s.snapshot;
615
- l.setOpen(n.isOpen), a.setTyping(n.isTyping), a.setOffline(!n.isConnected), a.updateTheme(x(e.theme)), n.isOpen ? a.show() : a.hide();
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();
616
615
  });
617
- o().then(
618
- () => h.connect().then((n) => {
616
+ n().then(
617
+ () => h.connect().then((o) => {
619
618
  var c;
620
- e.persist && s.persistSession(n.sessionId), s.setConnected(!0), t.onTransportChange((c = h.kind) != null ? c : "ws");
619
+ e.persist && s.persistSession(o.sessionId), s.setConnected(!0), t.onTransportChange((c = h.kind) != null ? c : "ws");
621
620
  })
622
- ).catch((n) => {
623
- t.onError(n), s.setConnected(!1), a.setOffline(!0);
621
+ ).catch((o) => {
622
+ t.onError(o), s.setConnected(!1), a.setOffline(!0);
624
623
  });
625
624
  const m = {
626
625
  transport: null,
@@ -637,24 +636,23 @@ function E(r) {
637
636
  return m;
638
637
  }
639
638
  function T() {
640
- var i, o;
639
+ var s, i;
641
640
  if (typeof document == "undefined") return;
642
641
  const r = document.currentScript;
643
642
  if (!r) return;
644
643
  const e = r.dataset;
645
644
  if (e.autoinit === "false") return;
646
- const t = e.org, s = e.assistant;
647
- if (!t || !s) {
648
- console.error("SpilkiWidget: data-org and data-assistant are required for auto init");
645
+ const t = e.org;
646
+ if (!t) {
647
+ console.error("SpilkiWidget: data-org and is required for auto init");
649
648
  return;
650
649
  }
651
650
  E({
652
651
  org: t,
653
- assistant: s,
654
652
  installationToken: e.installationToken,
655
653
  apiBase: e.apiBase,
656
- position: (i = e.position) != null ? i : void 0,
657
- theme: (o = e.theme) != null ? o : void 0
654
+ position: (s = e.position) != null ? s : void 0,
655
+ theme: (i = e.theme) != null ? i : void 0
658
656
  });
659
657
  }
660
658
  if (typeof window != "undefined") {