@opencx/widget 3.0.84 → 3.0.86

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.
Files changed (43) hide show
  1. package/dist/designs.cjs +24 -24
  2. package/dist/designs.cjs.map +1 -1
  3. package/dist/designs.js +3412 -3185
  4. package/dist/designs.js.map +1 -1
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.js +5 -3
  7. package/dist/index.js.map +1 -1
  8. package/dist/is-exhaustive-9o43S91P.cjs +2 -0
  9. package/dist/is-exhaustive-9o43S91P.cjs.map +1 -0
  10. package/dist/is-exhaustive-DGJzQK69.js +7 -0
  11. package/dist/is-exhaustive-DGJzQK69.js.map +1 -0
  12. package/dist/react.cjs +1 -1
  13. package/dist/react.js +2 -2
  14. package/dist/src/designs/react/components/Header.d.ts +3 -0
  15. package/dist/src/designs/react/components/lib/DynamicIcon.d.ts +6 -0
  16. package/dist/src/designs/react/components/lib/dialog.d.ts +8 -2
  17. package/dist/src/designs/react/hooks/useSetWidgetSize.d.ts +8 -0
  18. package/dist/src/headless/core/context/router.ctx.d.ts +6 -5
  19. package/dist/src/headless/core/context/session.ctx.d.ts +32 -1
  20. package/dist/src/headless/core/index.d.ts +4 -2
  21. package/dist/src/headless/core/types/icons.d.ts +3 -0
  22. package/dist/src/headless/core/types/widget-config.d.ts +45 -0
  23. package/dist/src/headless/core/utils/is-exhaustive.d.ts +1 -0
  24. package/dist/src/headless/react/hooks/useSessions.d.ts +32 -0
  25. package/dist/src/headless/react/hooks/useWidgetRouter.d.ts +1 -1
  26. package/dist/{useWidgetTrigger-38gyi4gE.js → useWidgetTrigger-Bi12WVrs.js} +59 -58
  27. package/dist/useWidgetTrigger-Bi12WVrs.js.map +1 -0
  28. package/dist/{useWidgetTrigger-OXlF9nHb.cjs → useWidgetTrigger-Bplu_1C-.cjs} +2 -2
  29. package/dist/useWidgetTrigger-Bplu_1C-.cjs.map +1 -0
  30. package/dist/{widget.ctx-r2Nzp00O.js → widget.ctx-DFFwNHvy.js} +254 -241
  31. package/dist/widget.ctx-DFFwNHvy.js.map +1 -0
  32. package/dist/widget.ctx-oIT8sGvJ.cjs +5 -0
  33. package/dist/widget.ctx-oIT8sGvJ.cjs.map +1 -0
  34. package/dist-embed/script.js +147 -82
  35. package/dist-embed/script.js.map +1 -1
  36. package/package.json +2 -1
  37. package/dist/src/designs/react/components/WidgetHeader.d.ts +0 -2
  38. package/dist/src/designs/react/hooks/useWidgetSize.d.ts +0 -4
  39. package/dist/useWidgetTrigger-38gyi4gE.js.map +0 -1
  40. package/dist/useWidgetTrigger-OXlF9nHb.cjs.map +0 -1
  41. package/dist/widget.ctx-CoJrM0OY.cjs +0 -5
  42. package/dist/widget.ctx-CoJrM0OY.cjs.map +0 -1
  43. package/dist/widget.ctx-r2Nzp00O.js.map +0 -1
@@ -6,45 +6,45 @@ const F = (d) => {
6
6
  }, _ = (d) => {
7
7
  const n = M({
8
8
  baseUrl: d.baseUrl
9
- }), i = {
9
+ }), a = {
10
10
  onRequest: d.onRequest,
11
11
  onResponse: d.onResponse,
12
12
  onError: d.onError || F
13
13
  };
14
- return n.use(i), n;
14
+ return n.use(a), n;
15
15
  };
16
16
  class T {
17
17
  constructor({ config: n }) {
18
- var a, s;
18
+ var o, e;
19
19
  this.userToken = null, this.constructClientOptions = (t) => {
20
- const e = this.config.apiUrl || "https://api.open.cx", o = {
20
+ const s = this.config.apiUrl || "https://api.open.cx", i = {
21
21
  "X-Bot-Token": this.config.token,
22
22
  "Content-Type": "application/json",
23
23
  Accept: "application/json",
24
24
  Authorization: t ? `Bearer ${t}` : void 0
25
25
  };
26
- return { baseUrl: e, headers: o };
26
+ return { baseUrl: s, headers: i };
27
27
  }, this.createOpenAPIClient = ({
28
28
  baseUrl: t,
29
- headers: e
29
+ headers: s
30
30
  }) => _({
31
31
  baseUrl: t,
32
- onRequest: ({ request: o }) => {
33
- Object.entries(e).forEach(([l, r]) => {
34
- r && o.headers.set(l, r);
32
+ onRequest: ({ request: i }) => {
33
+ Object.entries(s).forEach(([c, r]) => {
34
+ r && i.headers.set(c, r);
35
35
  });
36
36
  }
37
37
  }), this.setAuthToken = (t) => {
38
38
  this.userToken = t;
39
- const { baseUrl: e, headers: o } = this.constructClientOptions(t);
40
- this.client = this.createOpenAPIClient({ baseUrl: e, headers: o });
39
+ const { baseUrl: s, headers: i } = this.constructClientOptions(t);
40
+ this.client = this.createOpenAPIClient({ baseUrl: s, headers: i });
41
41
  }, this.getExternalWidgetConfig = async () => await this.client.GET("/backend/widget/v2/config", {
42
42
  params: { header: { "X-Bot-Token": this.config.token } }
43
43
  }), this.widgetPrelude = async () => await this.client.GET("/backend/widget/v2/prelude", {
44
44
  params: { header: { "X-Bot-Token": this.config.token } }
45
- }), this.sendMessage = async (t, e) => await this.client.POST("/backend/widget/v2/chat/send", {
45
+ }), this.sendMessage = async (t, s) => await this.client.POST("/backend/widget/v2/chat/send", {
46
46
  body: t,
47
- signal: e
47
+ signal: s
48
48
  }), this.createUnverifiedContact = async (t) => await this.client.POST(
49
49
  "/backend/widget/v2/contact/create-unverified",
50
50
  {
@@ -55,92 +55,92 @@ class T {
55
55
  body: t
56
56
  }), this.pollSessionAndHistory = async ({
57
57
  sessionId: t,
58
- lastMessageTimestamp: e,
59
- abortSignal: o
58
+ lastMessageTimestamp: s,
59
+ abortSignal: i
60
60
  }) => {
61
- const l = e ? { lastMessageTimestamp: e } : void 0;
61
+ const c = s ? { lastMessageTimestamp: s } : void 0;
62
62
  return await this.client.GET("/backend/widget/v2/poll/{sessionId}", {
63
- params: { path: { sessionId: t }, query: l },
64
- signal: o
63
+ params: { path: { sessionId: t }, query: c },
64
+ signal: i
65
65
  });
66
66
  }, this.getSessions = async ({
67
67
  cursor: t,
68
- filters: e,
69
- abortSignal: o
68
+ filters: s,
69
+ abortSignal: i
70
70
  }) => await this.client.GET("/backend/widget/v2/sessions", {
71
- params: { query: { cursor: t, filters: JSON.stringify(e) } },
72
- signal: o
71
+ params: { query: { cursor: t, filters: JSON.stringify(s) } },
72
+ signal: i
73
73
  }), this.uploadFile = async ({
74
74
  file: t,
75
- abortSignal: e,
76
- onProgress: o
77
- }) => new Promise((l, r) => {
75
+ abortSignal: s,
76
+ onProgress: i
77
+ }) => new Promise((c, r) => {
78
78
  var v;
79
- const g = new FormData();
80
- g.append("file", t);
81
- const c = new XMLHttpRequest();
82
- if (e && (e.addEventListener("abort", () => {
83
- c.abort(), r(new DOMException("Aborted", "AbortError"));
84
- }), e.aborted)) {
79
+ const h = new FormData();
80
+ h.append("file", t);
81
+ const l = new XMLHttpRequest();
82
+ if (s && (s.addEventListener("abort", () => {
83
+ l.abort(), r(new DOMException("Aborted", "AbortError"));
84
+ }), s.aborted)) {
85
85
  r(new DOMException("Aborted", "AbortError"));
86
86
  return;
87
87
  }
88
- c.upload.addEventListener("progress", (u) => {
89
- if (u.lengthComputable && o) {
90
- const m = Math.round(u.loaded / u.total * 100);
91
- o(m);
88
+ l.upload.addEventListener("progress", (u) => {
89
+ if (u.lengthComputable && i) {
90
+ const S = Math.round(u.loaded / u.total * 100);
91
+ i(S);
92
92
  }
93
- }), c.addEventListener("load", () => {
94
- if (c.status >= 200 && c.status < 300)
93
+ }), l.addEventListener("load", () => {
94
+ if (l.status >= 200 && l.status < 300)
95
95
  try {
96
- const u = JSON.parse(c.responseText);
97
- l(u);
96
+ const u = JSON.parse(l.responseText);
97
+ c(u);
98
98
  } catch (u) {
99
99
  r(new Error(`Failed to parse response: ${u}`));
100
100
  }
101
101
  else
102
- r(new Error(`Upload failed with status: ${c.status}`));
103
- }), c.addEventListener("error", () => {
102
+ r(new Error(`Upload failed with status: ${l.status}`));
103
+ }), l.addEventListener("error", () => {
104
104
  r(new Error("Network error occurred"));
105
- }), c.addEventListener("timeout", () => {
105
+ }), l.addEventListener("timeout", () => {
106
106
  r(new Error("Upload timed out"));
107
107
  });
108
- const { baseUrl: C } = this.constructClientOptions(this.userToken), p = `${C}/backend/widget/v2/upload`;
109
- c.open("POST", p), c.setRequestHeader("X-Bot-Token", this.config.token), this.userToken ?? ((v = this.config.user) == null ? void 0 : v.token) ? c.setRequestHeader("Authorization", `Bearer ${this.userToken}`) : console.error("User token not set"), c.send(g);
110
- }), this.vote = async (t) => await this.client.POST("/backend/widget/v2/chat/vote", { body: t }), this.resolveSession = async (t, e) => await this.client.POST("/backend/widget/v2/session/resolve", {
108
+ const { baseUrl: f } = this.constructClientOptions(this.userToken), p = `${f}/backend/widget/v2/upload`;
109
+ l.open("POST", p), l.setRequestHeader("X-Bot-Token", this.config.token), this.userToken ?? ((v = this.config.user) == null ? void 0 : v.token) ? l.setRequestHeader("Authorization", `Bearer ${this.userToken}`) : console.error("User token not set"), l.send(h);
110
+ }), this.vote = async (t) => await this.client.POST("/backend/widget/v2/chat/vote", { body: t }), this.resolveSession = async (t, s) => await this.client.POST("/backend/widget/v2/session/resolve", {
111
111
  body: t,
112
- signal: e
113
- }), this.config = n, this.userToken = ((a = n.user) == null ? void 0 : a.token) || null;
114
- const { baseUrl: i, headers: h } = this.constructClientOptions(
115
- (s = n.user) == null ? void 0 : s.token
112
+ signal: s
113
+ }), this.config = n, this.userToken = ((o = n.user) == null ? void 0 : o.token) || null;
114
+ const { baseUrl: a, headers: g } = this.constructClientOptions(
115
+ (e = n.user) == null ? void 0 : e.token
116
116
  );
117
- this.client = this.createOpenAPIClient({ baseUrl: i, headers: h });
117
+ this.client = this.createOpenAPIClient({ baseUrl: a, headers: g });
118
118
  }
119
119
  }
120
120
  class P {
121
121
  constructor(n) {
122
- this.subscribers = /* @__PURE__ */ new Set(), this.get = () => this.state, this.set = (i) => {
123
- O(this.state, i) || (this.state = i, this.notifySubscribers(i));
124
- }, this.setPartial = (i) => {
125
- if (i == null) return;
126
- const h = { ...this.state, ...i };
127
- this.set(h);
122
+ this.subscribers = /* @__PURE__ */ new Set(), this.get = () => this.state, this.set = (a) => {
123
+ O(this.state, a) || (this.state = a, this.notifySubscribers(a));
124
+ }, this.setPartial = (a) => {
125
+ if (a == null) return;
126
+ const g = { ...this.state, ...a };
127
+ this.set(g);
128
128
  }, this.reset = () => {
129
129
  this.set(this.initialState);
130
- }, this.notifySubscribers = (i) => {
131
- Array.from(this.subscribers).forEach((a) => {
130
+ }, this.notifySubscribers = (a) => {
131
+ Array.from(this.subscribers).forEach((o) => {
132
132
  try {
133
- a(i);
134
- } catch (s) {
135
- console.error(s);
133
+ o(a);
134
+ } catch (e) {
135
+ console.error(e);
136
136
  }
137
137
  });
138
- }, this.subscribe = (i) => (this.subscribers.add(i), () => {
139
- this.subscribers.delete(i);
138
+ }, this.subscribe = (a) => (this.subscribers.add(a), () => {
139
+ this.subscribers.delete(a);
140
140
  }), this.state = n, this.initialState = n;
141
141
  }
142
142
  }
143
- class A {
143
+ class R {
144
144
  constructor() {
145
145
  this.state = new P({
146
146
  isPolling: !1,
@@ -148,23 +148,23 @@ class A {
148
148
  }), this.abortController = new AbortController(), this.reset = () => {
149
149
  var n;
150
150
  this.abortController.abort("Resetting poller"), (n = this.stopPolling) == null || n.call(this), this.stopPolling = null;
151
- }, this.stopPolling = null, this.startPolling = (n, i) => {
151
+ }, this.stopPolling = null, this.startPolling = (n, a) => {
152
152
  if (this.stopPolling) return;
153
- const h = [], a = async () => {
153
+ const g = [], o = async () => {
154
154
  this.abortController = new AbortController(), this.state.setPartial({ isPolling: !0 });
155
155
  try {
156
156
  await n(this.abortController.signal);
157
- } catch (s) {
157
+ } catch (e) {
158
158
  if (this.abortController.signal.aborted)
159
159
  return;
160
- console.error("Failed to poll:", s), this.state.setPartial({ isError: !0 });
160
+ console.error("Failed to poll:", e), this.state.setPartial({ isError: !0 });
161
161
  } finally {
162
162
  this.state.setPartial({ isPolling: !1 });
163
163
  }
164
- this.abortController.signal.aborted ? console.log("Poller aborted, not scheduling anymore") : h.push(setTimeout(a, i));
164
+ this.abortController.signal.aborted ? console.log("Poller aborted, not scheduling anymore") : g.push(setTimeout(o, a));
165
165
  };
166
- a(), this.stopPolling = () => {
167
- h.forEach(clearTimeout), this.state.reset();
166
+ o(), this.stopPolling = () => {
167
+ g.forEach(clearTimeout), this.state.reset();
168
168
  };
169
169
  };
170
170
  }
@@ -172,7 +172,7 @@ class A {
172
172
  function D(d) {
173
173
  try {
174
174
  const n = d();
175
- return n instanceof Promise ? n.then((i) => ({ data: i })).catch((i) => ({ error: i })) : { data: n };
175
+ return n instanceof Promise ? n.then((a) => ({ data: a })).catch((a) => ({ error: a })) : { data: n };
176
176
  } catch (n) {
177
177
  return { error: n };
178
178
  }
@@ -180,51 +180,51 @@ function D(d) {
180
180
  class L {
181
181
  constructor({
182
182
  api: n,
183
- config: i,
184
- sessionCtx: h,
185
- messageCtx: a,
186
- sessionPollingIntervalSeconds: s
183
+ config: a,
184
+ sessionCtx: g,
185
+ messageCtx: o,
186
+ sessionPollingIntervalSeconds: e
187
187
  }) {
188
- this.poller = new A(), this.registerPolling = () => {
188
+ this.poller = new R(), this.registerPolling = () => {
189
189
  this.sessionCtx.sessionState.subscribe(({ session: t }) => {
190
- t != null && t.id ? this.poller.startPolling(async (e) => {
191
- this.hackAndSlash(t.id, e);
190
+ t != null && t.id ? this.poller.startPolling(async (s) => {
191
+ this.hackAndSlash(t.id, s);
192
192
  }, this.sessionPollingIntervalSeconds * 1e3) : this.poller.reset();
193
193
  });
194
- }, this.hackAndSlash = async (t, e) => {
195
- var g;
194
+ }, this.hackAndSlash = async (t, s) => {
195
+ var h;
196
196
  this.messageCtx.state.get().messages.length === 0 && this.messageCtx.state.setPartial({ isInitialFetchLoading: !0 });
197
- const o = this.messageCtx.state.get().messages, l = o.length > 0 ? (g = o[o.length - 1]) == null ? void 0 : g.timestamp : void 0, { data: r } = await this.api.pollSessionAndHistory({
197
+ const i = this.messageCtx.state.get().messages, c = i.length > 0 ? (h = i[i.length - 1]) == null ? void 0 : h.timestamp : void 0, { data: r } = await this.api.pollSessionAndHistory({
198
198
  sessionId: t,
199
- abortSignal: e,
200
- lastMessageTimestamp: l
199
+ abortSignal: s,
200
+ lastMessageTimestamp: c
201
201
  });
202
202
  if (r != null && r.session && (this.sessionCtx.sessionState.setPartial({ session: r.session }), this.sessionCtx.setSessions([r.session])), r != null && r.history && r.history.length > 0) {
203
- const c = this.messageCtx.state.get().messages, C = r.history.map(this.mapHistoryToMessage).filter(
204
- (x) => !c.some((p) => p.id === x.id)
203
+ const l = this.messageCtx.state.get().messages, f = r.history.map(this.mapHistoryToMessage).filter(
204
+ (x) => !l.some((p) => p.id === x.id)
205
205
  );
206
206
  this.messageCtx.state.setPartial({
207
- messages: [...c, ...C]
207
+ messages: [...l, ...f]
208
208
  });
209
209
  }
210
210
  this.messageCtx.state.get().isInitialFetchLoading && this.messageCtx.state.setPartial({ isInitialFetchLoading: !1 });
211
211
  }, this.mapHistoryToMessage = (t) => {
212
- var l, r;
213
- const e = {
212
+ var c, r;
213
+ const s = {
214
214
  id: t.publicId,
215
215
  timestamp: t.sentAt || "",
216
216
  attachments: t.attachments || void 0
217
217
  };
218
218
  if (t.sender.kind === "user")
219
219
  return {
220
- ...e,
220
+ ...s,
221
221
  type: "FROM_USER",
222
222
  content: t.content.text || "",
223
223
  deliveredAt: t.sentAt || ""
224
224
  };
225
225
  if (t.sender.kind === "agent")
226
226
  return {
227
- ...e,
227
+ ...s,
228
228
  type: "FROM_AGENT",
229
229
  component: "agent_message",
230
230
  data: {
@@ -237,87 +237,87 @@ class L {
237
237
  isAi: !1
238
238
  }
239
239
  };
240
- const o = t.actionCalls && t.actionCalls.length > 0 ? t.actionCalls[t.actionCalls.length - 1] : void 0;
240
+ const i = t.actionCalls && t.actionCalls.length > 0 ? t.actionCalls[t.actionCalls.length - 1] : void 0;
241
241
  return {
242
- ...e,
242
+ ...s,
243
243
  type: "FROM_BOT",
244
244
  component: "bot_message",
245
245
  agent: {
246
246
  id: null,
247
- name: ((l = this.config.bot) == null ? void 0 : l.name) || "",
247
+ name: ((c = this.config.bot) == null ? void 0 : c.name) || "",
248
248
  isAi: !0,
249
249
  avatar: ((r = this.config.bot) == null ? void 0 : r.avatar) || ""
250
250
  },
251
251
  data: {
252
252
  message: t.content.text || "",
253
- action: o ? {
254
- name: o.actionName,
255
- data: this.extractActionResult(o)
253
+ action: i ? {
254
+ name: i.actionName,
255
+ data: this.extractActionResult(i)
256
256
  } : void 0
257
257
  }
258
258
  };
259
259
  }, this.extractActionResult = (t) => {
260
- const e = t.result;
261
- if (e === null || typeof e != "object") return e;
262
- if ("responseBodyText" in e && typeof e.responseBodyText == "string") {
263
- const o = e.responseBodyText, l = D(() => JSON.parse(o)).data;
264
- if (l) return l;
260
+ const s = t.result;
261
+ if (s === null || typeof s != "object") return s;
262
+ if ("responseBodyText" in s && typeof s.responseBodyText == "string") {
263
+ const i = s.responseBodyText, c = D(() => JSON.parse(i)).data;
264
+ if (c) return c;
265
265
  }
266
266
  return t.result;
267
- }, this.api = n, this.config = i, this.sessionCtx = h, this.messageCtx = a, this.sessionPollingIntervalSeconds = s, this.registerPolling();
267
+ }, this.api = n, this.config = a, this.sessionCtx = g, this.messageCtx = o, this.sessionPollingIntervalSeconds = e, this.registerPolling();
268
268
  }
269
269
  }
270
270
  class B {
271
271
  constructor({
272
272
  config: n,
273
- api: i,
274
- storageCtx: h
273
+ api: a,
274
+ storageCtx: g
275
275
  }) {
276
- var a;
276
+ var o;
277
277
  this.shouldCollectData = () => {
278
- var s;
279
- return !!(!((s = this.state.get().contact) != null && s.token) && this.config.collectUserData);
278
+ var e;
279
+ return !!(!((e = this.state.get().contact) != null && e.token) && this.config.collectUserData);
280
280
  }, this.autoCreateUnverifiedUserIfNotExists = async () => {
281
- var s, t, e, o, l, r, g, c, C, x, p, b, v, u;
282
- if (!((s = this.config.user) != null && s.token)) {
283
- if (this.config.collectUserData && !((e = (t = this.config.user) == null ? void 0 : t.data) != null && e.email)) {
284
- if ((o = this.config.extraDataCollectionFields) != null && o.length)
281
+ var e, t, s, i, c, r, h, l, f, x, p, b, v, u;
282
+ if (!((e = this.config.user) != null && e.token)) {
283
+ if (this.config.collectUserData && !((s = (t = this.config.user) == null ? void 0 : t.data) != null && s.email)) {
284
+ if ((i = this.config.extraDataCollectionFields) != null && i.length)
285
285
  return;
286
- const m = await ((l = this.storageCtx) == null ? void 0 : l.getContactToken());
287
- m && await this.setUnverifiedContact(m);
286
+ const S = await ((c = this.storageCtx) == null ? void 0 : c.getContactToken());
287
+ S && await this.setUnverifiedContact(S);
288
288
  return;
289
289
  }
290
- if (!((g = (r = this.config.user) == null ? void 0 : r.data) != null && g.email)) {
291
- const m = await ((c = this.storageCtx) == null ? void 0 : c.getContactToken());
292
- if (m) {
293
- await this.setUnverifiedContact(m);
290
+ if (!((h = (r = this.config.user) == null ? void 0 : r.data) != null && h.email)) {
291
+ const S = await ((l = this.storageCtx) == null ? void 0 : l.getContactToken());
292
+ if (S) {
293
+ await this.setUnverifiedContact(S);
294
294
  return;
295
295
  }
296
296
  }
297
297
  await this.createUnverifiedContact({
298
- email: (x = (C = this.config.user) == null ? void 0 : C.data) == null ? void 0 : x.email,
298
+ email: (x = (f = this.config.user) == null ? void 0 : f.data) == null ? void 0 : x.email,
299
299
  non_verified_name: ((b = (p = this.config.user) == null ? void 0 : p.data) == null ? void 0 : b.name) || "Anonymous",
300
300
  non_verified_custom_data: (u = (v = this.config.user) == null ? void 0 : v.data) == null ? void 0 : u.customData
301
301
  });
302
302
  }
303
- }, this.createUnverifiedContact = async (s, t) => {
303
+ }, this.createUnverifiedContact = async (e, t) => {
304
304
  this.state.setPartial({ extraCollectedData: t });
305
305
  try {
306
306
  this.state.setPartial({
307
307
  isCreatingUnverifiedContact: !0,
308
308
  isErrorCreatingUnverifiedContact: !1
309
309
  });
310
- const { data: e } = await this.api.createUnverifiedContact(s);
311
- e != null && e.token ? await this.setUnverifiedContact(e.token) : this.state.setPartial({ isErrorCreatingUnverifiedContact: !0 });
310
+ const { data: s } = await this.api.createUnverifiedContact(e);
311
+ s != null && s.token ? await this.setUnverifiedContact(s.token) : this.state.setPartial({ isErrorCreatingUnverifiedContact: !0 });
312
312
  } finally {
313
313
  this.state.setPartial({ isCreatingUnverifiedContact: !1 });
314
314
  }
315
- }, this.setUnverifiedContact = async (s) => {
316
- var o, l, r, g;
317
- const t = await ((o = this.storageCtx) == null ? void 0 : o.getExternalContactId()), e = ((l = this.config.user) == null ? void 0 : l.externalId) || t || E();
318
- this.api.setAuthToken(s), await ((r = this.storageCtx) == null ? void 0 : r.setContactToken(s)), await ((g = this.storageCtx) == null ? void 0 : g.setExternalContactId(e)), this.state.setPartial({ contact: { token: s, externalId: e } });
319
- }, this.config = n, this.storageCtx = h, this.api = i, this.state = new P({
320
- contact: (a = n.user) != null && a.token ? {
315
+ }, this.setUnverifiedContact = async (e) => {
316
+ var i, c, r, h;
317
+ const t = await ((i = this.storageCtx) == null ? void 0 : i.getExternalContactId()), s = ((c = this.config.user) == null ? void 0 : c.externalId) || t || E();
318
+ this.api.setAuthToken(e), await ((r = this.storageCtx) == null ? void 0 : r.setContactToken(e)), await ((h = this.storageCtx) == null ? void 0 : h.setExternalContactId(s)), this.state.setPartial({ contact: { token: e, externalId: s } });
319
+ }, this.config = n, this.storageCtx = g, this.api = a, this.state = new P({
320
+ contact: (o = n.user) != null && o.token ? {
321
321
  token: n.user.token,
322
322
  // Set optional externalId from config... not local storage
323
323
  externalId: n.user.externalId
@@ -334,12 +334,13 @@ function y() {
334
334
  class q {
335
335
  constructor({
336
336
  api: n,
337
- contactCtx: i,
338
- sessionsPollingIntervalSeconds: h
337
+ contactCtx: a,
338
+ sessionsPollingIntervalSeconds: g
339
339
  }) {
340
- this.sessionsRefresher = new A(), this.sessionState = new P({
340
+ this.sessionsRefresher = new R(), this.sessionState = new P({
341
341
  session: null,
342
- isCreatingSession: !1
342
+ isCreatingSession: !1,
343
+ isResolvingSession: !1
343
344
  }), this.sessionsState = new P({
344
345
  data: [],
345
346
  cursor: void 0,
@@ -352,73 +353,75 @@ class q {
352
353
  }), this.reset = async () => {
353
354
  this.sessionState.reset();
354
355
  }, this.registerSessionsRefresherWrapper = () => {
355
- var a;
356
+ var o;
356
357
  // If the widget config was initially provided with a contact token, no state change would be triggered, so we just fetch
357
- (a = this.contactCtx.state.get().contact) != null && a.token && !this.sessionsState.get().didStartInitialFetch ? this.registerSessionsRefresher() : this.contactCtx.state.subscribe(({ contact: s }) => {
358
- s != null && s.token && !this.sessionsState.get().didStartInitialFetch && this.registerSessionsRefresher();
358
+ (o = this.contactCtx.state.get().contact) != null && o.token && !this.sessionsState.get().didStartInitialFetch ? this.registerSessionsRefresher() : this.contactCtx.state.subscribe(({ contact: e }) => {
359
+ e != null && e.token && !this.sessionsState.get().didStartInitialFetch && this.registerSessionsRefresher();
359
360
  });
360
361
  }, this.registerSessionsRefresher = () => {
361
362
  this.sessionsRefresher.startPolling(async () => {
362
363
  this.sessionsState.get().didStartInitialFetch === !1 && this.sessionsState.setPartial({ didStartInitialFetch: !0 }), await this.refreshSessions(), this.sessionsState.get().isInitialFetchLoading === !0 && this.sessionsState.setPartial({ isInitialFetchLoading: !1 });
363
364
  }, this.sessionsPollingIntervalSeconds * 1e3);
364
365
  }, this.createSession = async () => {
365
- var e;
366
+ var s;
366
367
  this.sessionState.setPartial({ session: null, isCreatingSession: !0 });
367
- const a = (e = this.contactCtx.state.get().contact) == null ? void 0 : e.externalId, { data: s, error: t } = await this.api.createSession({
368
- customData: a ? {
369
- external_id: a
368
+ const o = (s = this.contactCtx.state.get().contact) == null ? void 0 : s.externalId, { data: e, error: t } = await this.api.createSession({
369
+ customData: o ? {
370
+ external_id: o
370
371
  } : void 0
371
372
  });
372
- return s ? (this.sessionState.setPartial({ session: s, isCreatingSession: !1 }), s) : (console.error("Failed to create session:", t), null);
373
+ return e ? (this.sessionState.setPartial({ session: e, isCreatingSession: !1 }), e) : (this.sessionState.setPartial({ isCreatingSession: !1 }), console.error("Failed to create session:", t), null);
373
374
  }, this.loadMoreSessions = async () => {
374
375
  if (this.sessionsState.get().isLastPage) return;
375
- const { data: a } = await this.getSessions({
376
+ const { data: o } = await this.getSessions({
376
377
  cursor: this.sessionsState.get().cursor
377
378
  });
378
- if (a) {
379
- const t = [...this.sessionsState.get().data, ...a.items].filter(
380
- (e, o, l) => o === l.findIndex((r) => e.id === r.id)
379
+ if (o) {
380
+ const t = [...this.sessionsState.get().data, ...o.items].filter(
381
+ (s, i, c) => i === c.findIndex((r) => s.id === r.id)
381
382
  );
382
383
  this.sessionsState.setPartial({
383
384
  data: t,
384
- cursor: a.next || void 0,
385
- isLastPage: a.next === null
385
+ cursor: o.next || void 0,
386
+ isLastPage: o.next === null
386
387
  });
387
388
  }
388
- }, this.getSessions = async ({ cursor: a }) => {
389
- var t, e;
389
+ }, this.getSessions = async ({ cursor: o }) => {
390
+ var t, s;
390
391
  if (!((t = this.contactCtx.state.get().contact) != null && t.token)) return { data: null };
391
- const s = (e = this.contactCtx.state.get().contact) == null ? void 0 : e.externalId;
392
+ const e = (s = this.contactCtx.state.get().contact) == null ? void 0 : s.externalId;
392
393
  return await this.api.getSessions({
393
- cursor: a,
394
- filters: s ? {
395
- external_id: s
394
+ cursor: o,
395
+ filters: e ? {
396
+ external_id: e
396
397
  } : {}
397
398
  });
398
- }, this.setSessions = (a) => {
399
- const s = [...a, ...this.sessionsState.get().data].filter(
400
- (t, e, o) => e === o.findIndex((l) => t.id === l.id)
399
+ }, this.setSessions = (o) => {
400
+ const e = [...o, ...this.sessionsState.get().data].filter(
401
+ (t, s, i) => s === i.findIndex((c) => t.id === c.id)
401
402
  );
402
- this.sessionsState.setPartial({ data: s });
403
+ this.sessionsState.setPartial({ data: e });
403
404
  }, this.refreshSessions = async () => {
404
- const { data: a } = await this.getSessions({ cursor: void 0 });
405
- a && this.setSessions(a.items);
405
+ const { data: o } = await this.getSessions({ cursor: void 0 });
406
+ o && this.setSessions(o.items);
406
407
  }, this.resolveSession = async () => {
407
- const a = this.sessionState.get().session;
408
- if (!a || !a.isOpened) return;
409
- const { data: s } = await this.api.resolveSession({
410
- session_id: a.id
408
+ const o = this.sessionState.get().session;
409
+ if (!o || !o.isOpened)
410
+ return { success: !1, error: "Session is not opened" };
411
+ this.sessionState.setPartial({ isResolvingSession: !0 });
412
+ const { data: e, error: t } = await this.api.resolveSession({
413
+ session_id: o.id
411
414
  });
412
- s && this.sessionState.setPartial({ session: s });
413
- }, this.api = n, this.contactCtx = i, this.sessionsPollingIntervalSeconds = h, this.registerSessionsRefresherWrapper();
415
+ return e ? (this.sessionState.setPartial({ session: e, isResolvingSession: !1 }), { success: !0, data: e }) : (this.sessionState.setPartial({ isResolvingSession: !1 }), { success: !1, error: t });
416
+ }, this.api = n, this.contactCtx = a, this.sessionsPollingIntervalSeconds = g, this.registerSessionsRefresherWrapper();
414
417
  }
415
418
  }
416
419
  class $ {
417
420
  constructor({
418
421
  config: n,
419
- api: i,
420
- sessionCtx: h,
421
- contactCtx: a
422
+ api: a,
423
+ sessionCtx: g,
424
+ contactCtx: o
422
425
  }) {
423
426
  this.state = new P({
424
427
  messages: [],
@@ -427,15 +430,15 @@ class $ {
427
430
  isInitialFetchLoading: !1
428
431
  }), this.sendMessageAbortController = new AbortController(), this.reset = () => {
429
432
  this.sendMessageAbortController.abort("Resetting chat"), this.state.reset();
430
- }, this.sendMessage = async (s) => {
431
- var r, g, c, C, x, p, b, v;
432
- if (!s.content.trim() && (!s.attachments || s.attachments.length === 0)) {
433
+ }, this.sendMessage = async (e) => {
434
+ var r, h, l, f, x, p, b, v;
435
+ if (!e.content.trim() && (!e.attachments || e.attachments.length === 0)) {
433
436
  console.warn("Cannot send an empty message of no content or attachments");
434
437
  return;
435
438
  }
436
- const t = this.state.get().isSendingMessage, e = ((r = this.sessionCtx.sessionState.get().session) == null ? void 0 : r.assignee.kind) === "ai", o = this.state.get().messages, l = o.length > 0 ? o[o.length - 1] : void 0;
437
- if (e && t || // If last message is from user, then bot response did not arrive yet
438
- e && (l == null ? void 0 : l.type) === "FROM_USER") {
439
+ const t = this.state.get().isSendingMessage, s = ((r = this.sessionCtx.sessionState.get().session) == null ? void 0 : r.assignee.kind) === "ai", i = this.state.get().messages, c = i.length > 0 ? i[i.length - 1] : void 0;
440
+ if (s && t || // If last message is from user, then bot response did not arrive yet
441
+ s && (c == null ? void 0 : c.type) === "FROM_USER") {
439
442
  console.warn("Cannot send messages while awaiting AI response");
440
443
  return;
441
444
  }
@@ -443,21 +446,21 @@ class $ {
443
446
  try {
444
447
  this.state.setPartial({ isSendingMessage: !0 });
445
448
  const u = this.toUserMessage(
446
- s.content.trim(),
447
- s.attachments || void 0
448
- ), m = this.state.get().messages;
449
+ e.content.trim(),
450
+ e.attachments || void 0
451
+ ), S = this.state.get().messages;
449
452
  if (this.state.setPartial({
450
- messages: [...m, u]
451
- }), !((g = this.sessionCtx.sessionState.get().session) != null && g.id)) {
453
+ messages: [...S, u]
454
+ }), !((h = this.sessionCtx.sessionState.get().session) != null && h.id)) {
452
455
  if (!await this.sessionCtx.createSession()) {
453
456
  console.error("Failed to create session");
454
457
  return;
455
458
  }
456
459
  this.sessionCtx.refreshSessions();
457
460
  }
458
- const k = (c = this.sessionCtx.sessionState.get().session) == null ? void 0 : c.id;
461
+ const k = (l = this.sessionCtx.sessionState.get().session) == null ? void 0 : l.id;
459
462
  if (!k) return;
460
- const { data: f } = await this.api.sendMessage(
463
+ const { data: C } = await this.api.sendMessage(
461
464
  {
462
465
  uuid: u.id,
463
466
  bot_token: this.config.token,
@@ -466,36 +469,36 @@ class $ {
466
469
  body_properties: this.config.bodyProperties,
467
470
  session_id: k,
468
471
  content: u.content,
469
- attachments: s.attachments,
472
+ attachments: e.attachments,
470
473
  clientContext: this.config.context,
471
474
  custom_data: {
472
475
  ...this.config.messageCustomData || {},
473
- ...s.customData || {}
476
+ ...e.customData || {}
474
477
  },
475
478
  language: this.config.language
476
479
  },
477
480
  this.sendMessageAbortController.signal
478
481
  );
479
- if (f != null && f.success) {
480
- const w = this.toBotMessage(f);
482
+ if (C != null && C.success) {
483
+ const w = this.toBotMessage(C);
481
484
  if (w) {
482
485
  const I = this.state.get().messages;
483
486
  if (!!I.some(
484
- (R) => R.id === w.id
487
+ (A) => A.id === w.id
485
488
  )) {
486
489
  this.state.setPartial({
487
- lastAIResMightSolveUserIssue: ((C = f.autopilotResponse) == null ? void 0 : C.mightSolveUserIssue) || ((x = f.uiResponse) == null ? void 0 : x.mightSolveUserIssue)
490
+ lastAIResMightSolveUserIssue: ((f = C.autopilotResponse) == null ? void 0 : f.mightSolveUserIssue) || ((x = C.uiResponse) == null ? void 0 : x.mightSolveUserIssue)
488
491
  });
489
492
  return;
490
493
  }
491
494
  this.state.setPartial({
492
495
  messages: [...I, w],
493
- lastAIResMightSolveUserIssue: ((p = f.autopilotResponse) == null ? void 0 : p.mightSolveUserIssue) || ((b = f.uiResponse) == null ? void 0 : b.mightSolveUserIssue)
496
+ lastAIResMightSolveUserIssue: ((p = C.autopilotResponse) == null ? void 0 : p.mightSolveUserIssue) || ((b = C.uiResponse) == null ? void 0 : b.mightSolveUserIssue)
494
497
  });
495
498
  }
496
499
  } else {
497
500
  const w = this.toBotErrorMessage(
498
- ((v = f == null ? void 0 : f.error) == null ? void 0 : v.message) || "Unknown error occurred"
501
+ ((v = C == null ? void 0 : C.error) == null ? void 0 : v.message) || "Unknown error occurred"
499
502
  ), I = this.state.get().messages;
500
503
  this.state.setPartial({
501
504
  messages: [...I, w]
@@ -506,27 +509,27 @@ class $ {
506
509
  } finally {
507
510
  this.state.setPartial({ isSendingMessage: !1 });
508
511
  }
509
- }, this.toUserMessage = (s, t) => {
510
- const e = (() => {
511
- const o = this.contactCtx.state.get().extraCollectedData;
512
- return this.state.get().messages.length === 0 && o && Object.keys(o).length > 0 ? `${Object.entries(o).filter(([r, g]) => !!g).map(([r, g]) => `${r}: ${g}`).join(`
512
+ }, this.toUserMessage = (e, t) => {
513
+ const s = (() => {
514
+ const i = this.contactCtx.state.get().extraCollectedData;
515
+ return this.state.get().messages.length === 0 && i && Object.keys(i).length > 0 ? `${Object.entries(i).filter(([r, h]) => !!h).map(([r, h]) => `${r}: ${h}`).join(`
513
516
  `)}
514
517
 
515
- ${s}` : s;
518
+ ${e}` : e;
516
519
  })();
517
520
  return {
518
521
  id: y(),
519
522
  type: "FROM_USER",
520
- content: e,
523
+ content: s,
521
524
  deliveredAt: (/* @__PURE__ */ new Date()).toISOString(),
522
525
  attachments: t,
523
526
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
524
527
  };
525
- }, this.toBotMessage = (s) => {
528
+ }, this.toBotMessage = (e) => {
526
529
  var t;
527
- return s.success && s.autopilotResponse ? {
530
+ return e.success && e.autopilotResponse ? {
528
531
  type: "FROM_BOT",
529
- id: s.autopilotResponse.id || y(),
532
+ id: e.autopilotResponse.id || y(),
530
533
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
531
534
  component: "bot_message",
532
535
  agent: this.config.bot ? {
@@ -536,54 +539,64 @@ ${s}` : s;
536
539
  id: null
537
540
  } : void 0,
538
541
  data: {
539
- message: s.autopilotResponse.value.content,
540
- action: (t = s.uiResponse) != null && t.value.name ? {
541
- name: s.uiResponse.value.name,
542
- data: s.uiResponse.value.request_response
542
+ message: e.autopilotResponse.value.content,
543
+ action: (t = e.uiResponse) != null && t.value.name ? {
544
+ name: e.uiResponse.value.name,
545
+ data: e.uiResponse.value.request_response
543
546
  } : void 0
544
547
  }
545
548
  } : null;
546
- }, this.toBotErrorMessage = (s) => ({
549
+ }, this.toBotErrorMessage = (e) => ({
547
550
  type: "FROM_BOT",
548
551
  id: y(),
549
552
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
550
553
  component: "TEXT",
551
554
  data: {
552
- message: s,
555
+ message: e,
553
556
  variant: "error",
554
557
  action: void 0
555
558
  }
556
- }), this.config = n, this.api = i, this.sessionCtx = h, this.contactCtx = a;
559
+ }), this.config = n, this.api = a, this.sessionCtx = g, this.contactCtx = o;
557
560
  }
558
561
  }
559
562
  class N {
560
563
  constructor({
561
564
  config: n,
562
- contactCtx: i,
563
- sessionCtx: h,
564
- resetChat: a
565
+ contactCtx: a,
566
+ sessionCtx: g,
567
+ resetChat: o
565
568
  }) {
569
+ var e;
566
570
  this.registerRoutingListener = () => {
567
- this.contactCtx.state.subscribe(({ contact: s }) => {
568
- s != null && s.token && this.state.get().screen === "welcome" && this.state.setPartial({ screen: "sessions" });
571
+ this.contactCtx.state.subscribe(({ contact: t }) => {
572
+ var s;
573
+ t != null && t.token && this.state.get().screen === "welcome" && this.state.setPartial({
574
+ screen: (s = this.config.router) != null && s.chatScreenOnly ? "chat" : "sessions"
575
+ });
569
576
  }), this.sessionCtx.sessionsState.subscribe(
570
- ({ isInitialFetchLoading: s, data: t }) => {
571
- var e;
572
- t.length || ((e = this.config.router) == null ? void 0 : e.goToChatIfNoSessions) !== !1 && !s && this.state.get().screen !== "chat" && this.toChatScreen();
577
+ ({ isInitialFetchLoading: t, data: s }) => {
578
+ var i, c, r, h;
579
+ if ((i = this.config.router) != null && i.chatScreenOnly && // Do not route to a chat if we are currently inside one already
580
+ // This also applies to newly created sessions; the new session will be in `sessionState` before it is refreshed and included in `sessionsState`
581
+ !((c = this.sessionCtx.sessionState.get().session) != null && c.id)) {
582
+ const l = (r = s.find((f) => f.isOpened)) == null ? void 0 : r.id;
583
+ return l ? this.toChatScreen(l) : void 0;
584
+ }
585
+ s.length || ((h = this.config.router) == null ? void 0 : h.goToChatIfNoSessions) !== !1 && !t && this.state.get().screen !== "chat" && this.toChatScreen();
573
586
  }
574
587
  );
575
588
  }, this.toSessionsScreen = () => {
576
589
  this.resetChat(), this.state.setPartial({ screen: "sessions" });
577
- }, this.toChatScreen = (s) => {
578
- if (this.resetChat(), s) {
579
- const t = this.sessionCtx.sessionsState.get().data.find((e) => e.id === s);
580
- if (!t) return;
581
- this.sessionCtx.sessionState.setPartial({ session: t });
590
+ }, this.toChatScreen = (t) => {
591
+ if (this.resetChat(), t) {
592
+ const s = this.sessionCtx.sessionsState.get().data.find((i) => i.id === t);
593
+ if (!s) return;
594
+ this.sessionCtx.sessionState.setPartial({ session: s });
582
595
  }
583
596
  this.state.setPartial({ screen: "chat" });
584
- }, this.state = new P({
585
- screen: i.shouldCollectData() ? "welcome" : "sessions"
586
- }), this.config = n, this.contactCtx = i, this.sessionCtx = h, this.resetChat = a, this.registerRoutingListener();
597
+ }, this.config = n, this.contactCtx = a, this.sessionCtx = g, this.resetChat = o, this.state = new P({
598
+ screen: this.contactCtx.shouldCollectData() ? "welcome" : (e = this.config.router) != null && e.chatScreenOnly ? "chat" : "sessions"
599
+ }), this.registerRoutingListener();
587
600
  }
588
601
  }
589
602
  class H {
@@ -591,32 +604,32 @@ class H {
591
604
  this.KEYS = {
592
605
  contactToken: "opencx__widget__contactToken",
593
606
  externalContactId: "opencx__widget__externalContactId"
594
- }, this.setContactToken = async (i) => {
595
- await this.storage.set(this.KEYS.contactToken, i);
596
- }, this.getContactToken = async () => this.storage.get(this.KEYS.contactToken), this.setExternalContactId = async (i) => {
597
- await this.storage.set(this.KEYS.externalContactId, i);
607
+ }, this.setContactToken = async (a) => {
608
+ await this.storage.set(this.KEYS.contactToken, a);
609
+ }, this.getContactToken = async () => this.storage.get(this.KEYS.contactToken), this.setExternalContactId = async (a) => {
610
+ await this.storage.set(this.KEYS.externalContactId, a);
598
611
  }, this.getExternalContactId = async () => this.storage.get(this.KEYS.externalContactId), this.storage = n;
599
612
  }
600
613
  }
601
- const S = class S {
614
+ const m = class m {
602
615
  constructor({
603
616
  config: n,
604
- storage: i
617
+ storage: a
605
618
  }) {
606
619
  if (this.resetChat = () => {
607
620
  this.sessionCtx.reset(), this.messageCtx.reset();
608
- }, !S.pollingIntervalsSeconds)
621
+ }, !m.pollingIntervalsSeconds)
609
622
  throw Error(
610
623
  "Widget polling values are not defined, did you call WidgetCtx.initialize()"
611
624
  );
612
- this.config = n, this.api = new T({ config: n }), this.storageCtx = i ? new H({ storage: i }) : void 0, this.contactCtx = new B({
625
+ this.config = n, this.api = new T({ config: n }), this.storageCtx = a ? new H({ storage: a }) : void 0, this.contactCtx = new B({
613
626
  api: this.api,
614
627
  config: this.config,
615
628
  storageCtx: this.storageCtx
616
629
  }), this.sessionCtx = new q({
617
630
  api: this.api,
618
631
  contactCtx: this.contactCtx,
619
- sessionsPollingIntervalSeconds: S.pollingIntervalsSeconds.sessions
632
+ sessionsPollingIntervalSeconds: m.pollingIntervalsSeconds.sessions
620
633
  }), this.messageCtx = new $({
621
634
  config: this.config,
622
635
  api: this.api,
@@ -627,7 +640,7 @@ const S = class S {
627
640
  config: this.config,
628
641
  sessionCtx: this.sessionCtx,
629
642
  messageCtx: this.messageCtx,
630
- sessionPollingIntervalSeconds: S.pollingIntervalsSeconds.session
643
+ sessionPollingIntervalSeconds: m.pollingIntervalsSeconds.session
631
644
  }), this.routerCtx = new N({
632
645
  config: this.config,
633
646
  contactCtx: this.contactCtx,
@@ -636,25 +649,25 @@ const S = class S {
636
649
  });
637
650
  }
638
651
  };
639
- S.pollingIntervalsSeconds = null, S.initialize = async ({
652
+ m.pollingIntervalsSeconds = null, m.initialize = async ({
640
653
  config: n,
641
- storage: i
654
+ storage: a
642
655
  }) => {
643
- var a, s;
644
- const h = await new T({
656
+ var o, e;
657
+ const g = await new T({
645
658
  config: n
646
659
  }).getExternalWidgetConfig();
647
- return S.pollingIntervalsSeconds = {
648
- session: ((a = h.data) == null ? void 0 : a.sessionPollingIntervalSeconds) || 10,
649
- sessions: ((s = h.data) == null ? void 0 : s.sessionsPollingIntervalSeconds) || 60
650
- }, new S({
660
+ return m.pollingIntervalsSeconds = {
661
+ session: ((o = g.data) == null ? void 0 : o.sessionPollingIntervalSeconds) || 10,
662
+ sessions: ((e = g.data) == null ? void 0 : e.sessionsPollingIntervalSeconds) || 60
663
+ }, new m({
651
664
  config: n,
652
- storage: i
665
+ storage: a
653
666
  });
654
667
  };
655
- let U = S;
668
+ let U = m;
656
669
  export {
657
670
  P,
658
671
  U as W
659
672
  };
660
- //# sourceMappingURL=widget.ctx-r2Nzp00O.js.map
673
+ //# sourceMappingURL=widget.ctx-DFFwNHvy.js.map