@opencx/widget 3.0.39 → 3.0.41

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