@opencx/widget-core 4.0.10 → 4.0.11

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 (84) hide show
  1. package/dist/index.cjs +2 -2
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +2 -15
  4. package/dist/index.js +276 -182
  5. package/dist/index.js.map +1 -1
  6. package/dist/src/__tests__/api-caller.mock.d.ts +2 -0
  7. package/dist/src/__tests__/api-caller.mock.d.ts.map +1 -0
  8. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-anonymous.spec.d.ts +1 -0
  9. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-anonymous.spec.d.ts.map +1 -0
  10. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-with-user-data-provided-by-org.spec.d.ts +1 -0
  11. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-with-user-data-provided-by-org.spec.d.ts.map +1 -0
  12. package/dist/src/__tests__/context/contact/auth/manually-create-unverified-with-user-data-provided-by-user.spec.d.ts +1 -0
  13. package/dist/src/__tests__/context/contact/auth/manually-create-unverified-with-user-data-provided-by-user.spec.d.ts.map +1 -0
  14. package/dist/src/__tests__/context/contact/auth/with-secure-token.spec.d.ts +1 -0
  15. package/dist/src/__tests__/context/contact/auth/with-secure-token.spec.d.ts.map +1 -0
  16. package/dist/src/__tests__/context/contact/should-collect-data.spec.d.ts +1 -0
  17. package/dist/src/__tests__/context/contact/should-collect-data.spec.d.ts.map +1 -0
  18. package/dist/{__tests__ → src/__tests__}/test-utils.d.ts +39 -0
  19. package/dist/src/__tests__/test-utils.d.ts.map +1 -0
  20. package/dist/src/__tests__/utils/Poller.spec.d.ts +2 -0
  21. package/dist/src/__tests__/utils/Poller.spec.d.ts.map +1 -0
  22. package/dist/src/__tests__/utils/PrimitiveState.spec.d.ts +2 -0
  23. package/dist/src/__tests__/utils/PrimitiveState.spec.d.ts.map +1 -0
  24. package/dist/{api → src/api}/api-caller.d.ts +39 -0
  25. package/dist/src/api/api-caller.d.ts.map +1 -0
  26. package/dist/{api → src/api}/client.d.ts +1 -0
  27. package/dist/src/api/client.d.ts.map +1 -0
  28. package/dist/{api → src/api}/schema.d.ts +96 -16
  29. package/dist/src/api/schema.d.ts.map +1 -0
  30. package/dist/{context → src/context}/active-session-polling.ctx.d.ts +4 -2
  31. package/dist/src/context/active-session-polling.ctx.d.ts.map +1 -0
  32. package/dist/{context → src/context}/contact.ctx.d.ts +1 -0
  33. package/dist/src/context/contact.ctx.d.ts.map +1 -0
  34. package/dist/src/context/csat.ctx.d.ts +31 -0
  35. package/dist/src/context/csat.ctx.d.ts.map +1 -0
  36. package/dist/{context → src/context}/message.ctx.d.ts +3 -2
  37. package/dist/src/context/message.ctx.d.ts.map +1 -0
  38. package/dist/{context → src/context}/router.ctx.d.ts +1 -0
  39. package/dist/src/context/router.ctx.d.ts.map +1 -0
  40. package/dist/{context → src/context}/session.ctx.d.ts +3 -2
  41. package/dist/src/context/session.ctx.d.ts.map +1 -0
  42. package/dist/{context → src/context}/storage.ctx.d.ts +1 -0
  43. package/dist/src/context/storage.ctx.d.ts.map +1 -0
  44. package/dist/{context → src/context}/widget.ctx.d.ts +3 -0
  45. package/dist/src/context/widget.ctx.d.ts.map +1 -0
  46. package/dist/src/index.d.ts +17 -0
  47. package/dist/src/index.d.ts.map +1 -0
  48. package/dist/{types → src/types}/agent-or-bot.d.ts +1 -0
  49. package/dist/src/types/agent-or-bot.d.ts.map +1 -0
  50. package/dist/{types → src/types}/component-name.d.ts +1 -0
  51. package/dist/src/types/component-name.d.ts.map +1 -0
  52. package/dist/{types → src/types}/dtos.d.ts +1 -0
  53. package/dist/src/types/dtos.d.ts.map +1 -0
  54. package/dist/{types → src/types}/external-storage.d.ts +1 -0
  55. package/dist/src/types/external-storage.d.ts.map +1 -0
  56. package/dist/{types → src/types}/helpers.d.ts +2 -0
  57. package/dist/src/types/helpers.d.ts.map +1 -0
  58. package/dist/{types → src/types}/icons.d.ts +1 -0
  59. package/dist/src/types/icons.d.ts.map +1 -0
  60. package/dist/{types → src/types}/json-value.d.ts +1 -0
  61. package/dist/src/types/json-value.d.ts.map +1 -0
  62. package/dist/{types → src/types}/messages.d.ts +43 -10
  63. package/dist/src/types/messages.d.ts.map +1 -0
  64. package/dist/{types → src/types}/widget-config.d.ts +1 -0
  65. package/dist/src/types/widget-config.d.ts.map +1 -0
  66. package/dist/{utils → src/utils}/Poller.d.ts +1 -0
  67. package/dist/src/utils/Poller.d.ts.map +1 -0
  68. package/dist/{utils → src/utils}/PrimitiveState.d.ts +1 -0
  69. package/dist/src/utils/PrimitiveState.d.ts.map +1 -0
  70. package/dist/{utils → src/utils}/is-exhaustive.d.ts +1 -0
  71. package/dist/src/utils/is-exhaustive.d.ts.map +1 -0
  72. package/dist/{utils → src/utils}/run-catching.d.ts +1 -0
  73. package/dist/src/utils/run-catching.d.ts.map +1 -0
  74. package/dist/{utils → src/utils}/uuid.d.ts +1 -0
  75. package/dist/src/utils/uuid.d.ts.map +1 -0
  76. package/package.json +3 -3
  77. package/dist/__tests__/api-caller.mock.d.ts +0 -1
  78. package/dist/__tests__/context/contact/auth/auto-create-unverified-anonymous.spec.d.ts +0 -0
  79. package/dist/__tests__/context/contact/auth/auto-create-unverified-with-user-data-provided-by-org.spec.d.ts +0 -0
  80. package/dist/__tests__/context/contact/auth/manually-create-unverified-with-user-data-provided-by-user.spec.d.ts +0 -0
  81. package/dist/__tests__/context/contact/auth/with-secure-token.spec.d.ts +0 -0
  82. package/dist/__tests__/context/contact/should-collect-data.spec.d.ts +0 -0
  83. package/dist/__tests__/utils/Poller.spec.d.ts +0 -1
  84. package/dist/__tests__/utils/PrimitiveState.spec.d.ts +0 -1
package/dist/index.js CHANGED
@@ -1,21 +1,21 @@
1
- import _ from "openapi-fetch";
2
- import B from "lodash.isequal";
1
+ import F from "openapi-fetch";
2
+ import L from "lodash.isequal";
3
3
  import { v4 as O } from "uuid";
4
- const L = (d) => {
5
- console.log(d.error);
6
- }, $ = (d) => {
7
- const n = _({
8
- baseUrl: d.baseUrl
4
+ const q = (g) => {
5
+ console.log(g.error);
6
+ }, B = (g) => {
7
+ const a = F({
8
+ baseUrl: g.baseUrl
9
9
  }), o = {
10
- onRequest: d.onRequest,
11
- onResponse: d.onResponse,
12
- onError: d.onError || L
10
+ onRequest: g.onRequest,
11
+ onResponse: g.onResponse,
12
+ onError: g.onError || q
13
13
  };
14
- return n.use(o), n;
14
+ return a.use(o), a;
15
15
  };
16
- class M {
17
- constructor({ config: n }) {
18
- var g, e;
16
+ class U {
17
+ constructor({ config: a }) {
18
+ var h, e;
19
19
  this.userToken = null, this.constructClientOptions = (t) => {
20
20
  const s = this.config.apiUrl || "https://api.open.cx", i = {
21
21
  "X-Bot-Token": this.config.token,
@@ -27,11 +27,11 @@ class M {
27
27
  }, this.createOpenAPIClient = ({
28
28
  baseUrl: t,
29
29
  headers: s
30
- }) => $({
30
+ }) => B({
31
31
  baseUrl: t,
32
32
  onRequest: ({ request: i }) => {
33
- Object.entries(s).forEach(([r, a]) => {
34
- a && i.headers.set(r, a);
33
+ Object.entries(s).forEach(([r, n]) => {
34
+ n && i.headers.set(r, n);
35
35
  });
36
36
  }
37
37
  }), this.setAuthToken = (t) => {
@@ -74,21 +74,21 @@ class M {
74
74
  file: t,
75
75
  abortSignal: s,
76
76
  onProgress: i
77
- }) => new Promise((r, a) => {
77
+ }) => new Promise((r, n) => {
78
78
  var b;
79
- const h = new FormData();
80
- h.append("file", t);
79
+ const d = new FormData();
80
+ d.append("file", t);
81
81
  const l = new XMLHttpRequest();
82
82
  if (s && (s.addEventListener("abort", () => {
83
- l.abort(), a(new DOMException("Aborted", "AbortError"));
83
+ l.abort(), n(new DOMException("Aborted", "AbortError"));
84
84
  }), s.aborted)) {
85
- a(new DOMException("Aborted", "AbortError"));
85
+ n(new DOMException("Aborted", "AbortError"));
86
86
  return;
87
87
  }
88
88
  l.upload.addEventListener("progress", (f) => {
89
89
  if (f.lengthComputable && i) {
90
- const S = Math.round(f.loaded / f.total * 100);
91
- i(S);
90
+ const C = Math.round(f.loaded / f.total * 100);
91
+ i(C);
92
92
  }
93
93
  }), l.addEventListener("load", () => {
94
94
  if (l.status >= 200 && l.status < 300)
@@ -96,33 +96,36 @@ class M {
96
96
  const f = JSON.parse(l.responseText);
97
97
  r(f);
98
98
  } catch (f) {
99
- a(new Error(`Failed to parse response: ${f}`));
99
+ n(new Error(`Failed to parse response: ${f}`));
100
100
  }
101
101
  else
102
- a(new Error(`Upload failed with status: ${l.status}`));
102
+ n(new Error(`Upload failed with status: ${l.status}`));
103
103
  }), l.addEventListener("error", () => {
104
- a(new Error("Network error occurred"));
104
+ n(new Error("Network error occurred"));
105
105
  }), l.addEventListener("timeout", () => {
106
- a(new Error("Upload timed out"));
106
+ n(new Error("Upload timed out"));
107
107
  });
108
- const { baseUrl: p } = this.constructClientOptions(this.userToken), m = `${p}/backend/widget/v2/upload`;
109
- l.open("POST", m), l.setRequestHeader("X-Bot-Token", this.config.token), this.userToken ?? ((b = this.config.user) == null ? void 0 : b.token) ? l.setRequestHeader("Authorization", `Bearer ${this.userToken}`) : console.error("User token not set"), l.send(h);
108
+ const { baseUrl: m } = this.constructClientOptions(this.userToken), x = `${m}/backend/widget/v2/upload`;
109
+ l.open("POST", x), l.setRequestHeader("X-Bot-Token", this.config.token), this.userToken ?? ((b = this.config.user) == null ? void 0 : b.token) ? l.setRequestHeader("Authorization", `Bearer ${this.userToken}`) : console.error("User token not set"), l.send(d);
110
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
112
  signal: s
113
113
  }), this.createStateCheckpoint = async (t) => await this.client.POST("/backend/widget/v2/checkpoint", {
114
114
  body: t
115
- }), this.config = n, this.userToken = ((g = n.user) == null ? void 0 : g.token) || null;
115
+ }), this.submitCsat = async (t) => await this.client.POST("/backend/widget/v2/submit-csat", { body: t }), this.config = a, this.userToken = ((h = a.user) == null ? void 0 : h.token) || null;
116
116
  const { baseUrl: o, headers: c } = this.constructClientOptions(
117
- (e = n.user) == null ? void 0 : e.token
117
+ (e = a.user) == null ? void 0 : e.token
118
118
  );
119
119
  this.client = this.createOpenAPIClient({ baseUrl: o, headers: c });
120
120
  }
121
121
  }
122
- class P {
123
- constructor(n) {
122
+ function $(g, a) {
123
+ console.error(`Missing case for ${g} in ${a}`);
124
+ }
125
+ class y {
126
+ constructor(a) {
124
127
  this.subscribers = /* @__PURE__ */ new Set(), this.get = () => this.state, this.set = (o) => {
125
- B(this.state, o) || (this.state = o, this.notifySubscribers(o));
128
+ L(this.state, o) || (this.state = o, this.notifySubscribers(o));
126
129
  }, this.setPartial = (o) => {
127
130
  if (o == null) return;
128
131
  const c = { ...this.state, ...o };
@@ -130,32 +133,32 @@ class P {
130
133
  }, this.reset = () => {
131
134
  this.set(this.initialState);
132
135
  }, this.notifySubscribers = (o) => {
133
- Array.from(this.subscribers).forEach((g) => {
136
+ Array.from(this.subscribers).forEach((h) => {
134
137
  try {
135
- g(o);
138
+ h(o);
136
139
  } catch (e) {
137
140
  console.error(e);
138
141
  }
139
142
  });
140
143
  }, this.subscribe = (o) => (this.subscribers.add(o), () => {
141
144
  this.subscribers.delete(o);
142
- }), this.state = n, this.initialState = n;
145
+ }), this.state = a, this.initialState = a;
143
146
  }
144
147
  }
145
- class F {
148
+ class _ {
146
149
  constructor() {
147
- this.state = new P({
150
+ this.state = new y({
148
151
  isPolling: !1,
149
152
  isError: !1
150
153
  }), this.abortController = new AbortController(), this.reset = () => {
151
- var n;
152
- this.abortController.abort("Resetting poller"), (n = this.stopPolling) == null || n.call(this), this.stopPolling = null;
153
- }, this.stopPolling = null, this.startPolling = (n, o) => {
154
+ var a;
155
+ this.abortController.abort("Resetting poller"), (a = this.stopPolling) == null || a.call(this), this.stopPolling = null;
156
+ }, this.stopPolling = null, this.startPolling = (a, o) => {
154
157
  if (this.stopPolling) return;
155
- const c = [], g = async () => {
158
+ const c = [], h = async () => {
156
159
  this.abortController = new AbortController(), this.state.setPartial({ isPolling: !0 });
157
160
  try {
158
- await n(this.abortController.signal);
161
+ await a(this.abortController.signal);
159
162
  } catch (e) {
160
163
  if (this.abortController.signal.aborted)
161
164
  return;
@@ -163,55 +166,55 @@ class F {
163
166
  } finally {
164
167
  this.state.setPartial({ isPolling: !1 });
165
168
  }
166
- this.abortController.signal.aborted ? console.log("Poller aborted, not scheduling anymore") : c.push(setTimeout(g, o));
169
+ this.abortController.signal.aborted ? console.log("Poller aborted, not scheduling anymore") : c.push(setTimeout(h, o));
167
170
  };
168
- g(), this.stopPolling = () => {
171
+ h(), this.stopPolling = () => {
169
172
  c.forEach(clearTimeout), this.state.reset();
170
173
  };
171
174
  };
172
175
  }
173
176
  }
174
- function q(d) {
177
+ function N(g) {
175
178
  try {
176
- const n = d();
177
- return n instanceof Promise ? n.then((o) => ({ data: o })).catch((o) => ({ error: o })) : { data: n };
178
- } catch (n) {
179
- return { error: n };
179
+ const a = g();
180
+ return a instanceof Promise ? a.then((o) => ({ data: o })).catch((o) => ({ error: o })) : { data: a };
181
+ } catch (a) {
182
+ return { error: a };
180
183
  }
181
184
  }
182
- class N {
185
+ class Y {
183
186
  constructor({
184
- api: n,
187
+ api: a,
185
188
  config: o,
186
189
  sessionCtx: c,
187
- messageCtx: g,
190
+ messageCtx: h,
188
191
  sessionPollingIntervalSeconds: e
189
192
  }) {
190
- this.poller = new F(), this.registerPolling = () => {
193
+ this.poller = new _(), this.registerPolling = () => {
191
194
  this.sessionCtx.sessionState.subscribe(({ session: t }) => {
192
195
  t != null && t.id ? this.poller.startPolling(async (s) => {
193
196
  this.hackAndSlash(t.id, s);
194
197
  }, this.sessionPollingIntervalSeconds * 1e3) : this.poller.reset();
195
198
  });
196
199
  }, this.hackAndSlash = async (t, s) => {
197
- var h;
200
+ var d;
198
201
  this.messageCtx.state.get().messages.length === 0 && this.messageCtx.state.setPartial({ isInitialFetchLoading: !0 });
199
- const i = this.messageCtx.state.get().messages, r = i.length > 0 ? ((h = i[i.length - 1]) == null ? void 0 : h.timestamp) ?? void 0 : void 0, { data: a } = await this.api.pollSessionAndHistory({
202
+ const i = this.messageCtx.state.get().messages, r = i.length > 0 ? ((d = i[i.length - 1]) == null ? void 0 : d.timestamp) ?? void 0 : void 0, { data: n } = await this.api.pollSessionAndHistory({
200
203
  sessionId: t,
201
204
  abortSignal: s,
202
205
  lastMessageTimestamp: r
203
206
  });
204
- if (a != null && a.session && (this.sessionCtx.sessionState.setPartial({ session: a.session }), this.sessionCtx.setSessions([a.session])), a != null && a.history && a.history.length > 0) {
205
- const l = this.messageCtx.state.get().messages, p = a.history.map(this.mapHistoryToMessage).filter(
206
- (v) => !l.some((m) => m.id === v.id)
207
+ if (n != null && n.session && (this.sessionCtx.sessionState.setPartial({ session: n.session }), this.sessionCtx.setSessions([n.session])), n != null && n.history && n.history.length > 0) {
208
+ const l = this.messageCtx.state.get().messages, m = n.history.map(this.mapHistoryToMessage).filter((S) => S !== null).filter(
209
+ (S) => !l.some((x) => x.id === S.id)
207
210
  );
208
211
  this.messageCtx.state.setPartial({
209
- messages: [...l, ...p]
212
+ messages: [...l, ...m]
210
213
  });
211
214
  }
212
215
  this.messageCtx.state.get().isInitialFetchLoading && this.messageCtx.state.setPartial({ isInitialFetchLoading: !1 });
213
216
  }, this.mapHistoryToMessage = (t) => {
214
- var r, a;
217
+ var i, r;
215
218
  const s = {
216
219
  id: t.publicId,
217
220
  timestamp: t.sentAt || "",
@@ -220,14 +223,14 @@ class N {
220
223
  if (t.sender.kind === "user")
221
224
  return {
222
225
  ...s,
223
- type: "FROM_USER",
226
+ type: "USER",
224
227
  content: t.content.text || "",
225
228
  deliveredAt: t.sentAt || ""
226
229
  };
227
230
  if (t.sender.kind === "agent")
228
231
  return {
229
232
  ...s,
230
- type: "FROM_AGENT",
233
+ type: "AGENT",
231
234
  component: "agent_message",
232
235
  data: {
233
236
  message: t.content.text || ""
@@ -239,66 +242,116 @@ class N {
239
242
  isAi: !1
240
243
  }
241
244
  };
242
- const i = t.actionCalls && t.actionCalls.length > 0 ? t.actionCalls[t.actionCalls.length - 1] : void 0;
243
- return {
244
- ...s,
245
- type: "FROM_BOT",
246
- component: "bot_message",
247
- agent: {
248
- id: null,
249
- name: ((r = this.config.bot) == null ? void 0 : r.name) || "",
250
- isAi: !0,
251
- avatar: ((a = this.config.bot) == null ? void 0 : a.avatar) || ""
252
- },
253
- data: {
254
- message: t.content.text || "",
255
- action: i ? {
256
- name: i.actionName,
257
- data: this.extractActionResult(i)
258
- } : void 0
259
- }
260
- };
245
+ if (t.sender.kind === "ai") {
246
+ const n = t.actionCalls && t.actionCalls.length > 0 ? t.actionCalls[t.actionCalls.length - 1] : void 0;
247
+ return {
248
+ ...s,
249
+ type: "AI",
250
+ component: "bot_message",
251
+ agent: {
252
+ id: null,
253
+ name: ((i = this.config.bot) == null ? void 0 : i.name) || "",
254
+ isAi: !0,
255
+ avatar: ((r = this.config.bot) == null ? void 0 : r.avatar) || ""
256
+ },
257
+ data: {
258
+ message: t.content.text || "",
259
+ action: n ? {
260
+ name: n.actionName,
261
+ data: this.extractActionResult(n)
262
+ } : void 0
263
+ }
264
+ };
265
+ }
266
+ if (t.sender.kind === "system") {
267
+ const n = this.constructSystemMessage(t);
268
+ return n === null ? null : { ...n };
269
+ }
270
+ return null;
271
+ }, this.constructSystemMessage = (t) => {
272
+ if (!t || !t.systemMessagePayload) return null;
273
+ switch (t.systemMessagePayload.type) {
274
+ case "state_checkpoint":
275
+ return {
276
+ id: t.publicId,
277
+ type: "SYSTEM",
278
+ subtype: "state_checkpoint",
279
+ data: { payload: t.systemMessagePayload.payload },
280
+ timestamp: t.sentAt || "",
281
+ attachments: void 0
282
+ };
283
+ case "csat_requested":
284
+ return {
285
+ id: t.publicId,
286
+ type: "SYSTEM",
287
+ subtype: "csat_requested",
288
+ data: { payload: void 0 },
289
+ timestamp: t.sentAt || "",
290
+ attachments: void 0
291
+ };
292
+ case "csat_submitted":
293
+ return {
294
+ id: t.publicId,
295
+ type: "SYSTEM",
296
+ subtype: "csat_submitted",
297
+ data: {
298
+ payload: {
299
+ score: t.systemMessagePayload.payload.score ?? void 0,
300
+ feedback: t.systemMessagePayload.payload.feedback ?? void 0
301
+ }
302
+ },
303
+ timestamp: t.sentAt || "",
304
+ attachments: void 0
305
+ };
306
+ case "none":
307
+ return null;
308
+ default:
309
+ return $(
310
+ t.systemMessagePayload,
311
+ this.constructSystemMessage.name
312
+ ), null;
313
+ }
261
314
  }, this.extractActionResult = (t) => {
262
315
  const s = t.result;
263
316
  if (s === null || typeof s != "object") return s;
264
317
  if ("responseBodyText" in s && typeof s.responseBodyText == "string") {
265
- const i = s.responseBodyText, r = q(() => JSON.parse(i)).data;
318
+ const i = s.responseBodyText, r = N(() => JSON.parse(i)).data;
266
319
  if (r) return r;
267
320
  }
268
321
  return t.result;
269
- }, this.api = n, this.config = o, this.sessionCtx = c, this.messageCtx = g, this.sessionPollingIntervalSeconds = e, this.registerPolling();
322
+ }, this.api = a, this.config = o, this.sessionCtx = c, this.messageCtx = h, this.sessionPollingIntervalSeconds = e, this.registerPolling();
270
323
  }
271
324
  }
272
325
  class H {
273
326
  constructor({
274
- config: n,
327
+ config: a,
275
328
  api: o,
276
329
  storageCtx: c
277
330
  }) {
278
- var g;
331
+ var h;
279
332
  this.shouldCollectData = () => {
280
333
  var e;
281
334
  return !!(!((e = this.state.get().contact) != null && e.token) && this.config.collectUserData);
282
335
  }, this.autoCreateUnverifiedUserIfNotExists = async () => {
283
- var e, t, s, i, r, a, h, l, p, v, m, w, b, f;
336
+ var e, t, s, i, r, n, d, l, m, S, x, w, b, f;
284
337
  if (!((e = this.config.user) != null && e.token)) {
285
338
  if (this.config.collectUserData && !((s = (t = this.config.user) == null ? void 0 : t.data) != null && s.email)) {
286
339
  if ((i = this.config.extraDataCollectionFields) != null && i.length)
287
340
  return;
288
- const S = await ((r = this.storageCtx) == null ? void 0 : r.getContactToken());
289
- S && await this.setUnverifiedContact(S);
341
+ const C = await ((r = this.storageCtx) == null ? void 0 : r.getContactToken());
342
+ C && await this.setUnverifiedContact(C);
290
343
  return;
291
344
  }
292
- if (!((h = (a = this.config.user) == null ? void 0 : a.data) != null && h.email)) {
293
- const S = await ((l = this.storageCtx) == null ? void 0 : l.getContactToken());
294
- if (S) {
295
- await this.setUnverifiedContact(S);
345
+ if (!((d = (n = this.config.user) == null ? void 0 : n.data) != null && d.email)) {
346
+ const C = await ((l = this.storageCtx) == null ? void 0 : l.getContactToken());
347
+ if (C) {
348
+ await this.setUnverifiedContact(C);
296
349
  return;
297
350
  }
298
351
  }
299
352
  await this.createUnverifiedContact({
300
- email: (v = (p = this.config.user) == null ? void 0 : p.data) == null ? void 0 : v.email,
301
- non_verified_name: ((w = (m = this.config.user) == null ? void 0 : m.data) == null ? void 0 : w.name) || "Anonymous",
353
+ email: (S = (m = this.config.user) == null ? void 0 : m.data) == null ? void 0 : S.email,
354
+ non_verified_name: ((w = (x = this.config.user) == null ? void 0 : x.data) == null ? void 0 : w.name) || "Anonymous",
302
355
  non_verified_custom_data: (f = (b = this.config.user) == null ? void 0 : b.data) == null ? void 0 : f.customData
303
356
  });
304
357
  }
@@ -315,14 +368,14 @@ class H {
315
368
  this.state.setPartial({ isCreatingUnverifiedContact: !1 });
316
369
  }
317
370
  }, this.setUnverifiedContact = async (e) => {
318
- var i, r, a, h;
371
+ var i, r, n, d;
319
372
  const t = await ((i = this.storageCtx) == null ? void 0 : i.getExternalContactId()), s = ((r = this.config.user) == null ? void 0 : r.externalId) || t || O();
320
- this.api.setAuthToken(e), await ((a = this.storageCtx) == null ? void 0 : a.setContactToken(e)), await ((h = this.storageCtx) == null ? void 0 : h.setExternalContactId(s)), this.state.setPartial({ contact: { token: e, externalId: s } });
321
- }, this.config = n, this.storageCtx = c, this.api = o, this.state = new P({
322
- contact: (g = n.user) != null && g.token ? {
323
- token: n.user.token,
373
+ this.api.setAuthToken(e), await ((n = this.storageCtx) == null ? void 0 : n.setContactToken(e)), await ((d = this.storageCtx) == null ? void 0 : d.setExternalContactId(s)), this.state.setPartial({ contact: { token: e, externalId: s } });
374
+ }, this.config = a, this.storageCtx = c, this.api = o, this.state = new y({
375
+ contact: (h = a.user) != null && h.token ? {
376
+ token: a.user.token,
324
377
  // Set optional externalId from config... not local storage
325
- externalId: n.user.externalId
378
+ externalId: a.user.externalId
326
379
  } : null,
327
380
  extraCollectedData: void 0,
328
381
  isCreatingUnverifiedContact: !1,
@@ -330,21 +383,60 @@ class H {
330
383
  }), this.autoCreateUnverifiedUserIfNotExists();
331
384
  }
332
385
  }
333
- function k() {
386
+ function P() {
334
387
  return O();
335
388
  }
336
389
  class X {
337
390
  constructor({
338
- config: n,
391
+ config: a,
392
+ api: o,
393
+ sessionCtx: c,
394
+ messageCtx: h
395
+ }) {
396
+ this.submitCsat = async (e) => {
397
+ var n;
398
+ const t = (n = this.sessionCtx.sessionState.get().session) == null ? void 0 : n.id;
399
+ if (!t)
400
+ return { data: null, error: "No session id found" };
401
+ const s = P();
402
+ this.messageCtx.state.setPartial({
403
+ messages: [
404
+ ...this.messageCtx.state.get().messages,
405
+ {
406
+ id: s,
407
+ type: "SYSTEM",
408
+ subtype: "csat_submitted",
409
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
410
+ data: {
411
+ payload: {
412
+ score: e.score,
413
+ feedback: e.feedback
414
+ }
415
+ }
416
+ }
417
+ ]
418
+ });
419
+ const { data: i, error: r } = await this.api.submitCsat({
420
+ ...e,
421
+ system_message_uuid: s,
422
+ session_id: t
423
+ });
424
+ return { data: i, error: r };
425
+ }, this.config = a, this.api = o, this.sessionCtx = c, this.messageCtx = h;
426
+ }
427
+ }
428
+ class G {
429
+ constructor({
430
+ config: a,
339
431
  api: o,
340
432
  contactCtx: c,
341
- sessionsPollingIntervalSeconds: g
433
+ sessionsPollingIntervalSeconds: h
342
434
  }) {
343
- this.sessionsRefresher = new F(), this.sessionState = new P({
435
+ this.sessionsRefresher = new _(), this.sessionState = new y({
344
436
  session: null,
345
437
  isCreatingSession: !1,
346
438
  isResolvingSession: !1
347
- }), this.sessionsState = new P({
439
+ }), this.sessionsState = new y({
348
440
  data: [],
349
441
  cursor: void 0,
350
442
  isLastPage: !1,
@@ -382,7 +474,7 @@ class X {
382
474
  });
383
475
  if (e) {
384
476
  const s = [...this.sessionsState.get().data, ...e.items].filter(
385
- (i, r, a) => r === a.findIndex((h) => i.id === h.id)
477
+ (i, r, n) => r === n.findIndex((d) => i.id === d.id)
386
478
  );
387
479
  this.sessionsState.setPartial({
388
480
  data: s,
@@ -402,7 +494,7 @@ class X {
402
494
  });
403
495
  }, this.setSessions = (e) => {
404
496
  const t = [...e, ...this.sessionsState.get().data].filter(
405
- (s, i, r) => i === r.findIndex((a) => s.id === a.id)
497
+ (s, i, r) => i === r.findIndex((n) => s.id === n.id)
406
498
  );
407
499
  this.sessionsState.setPartial({ data: t });
408
500
  }, this.refreshSessions = async () => {
@@ -426,17 +518,17 @@ class X {
426
518
  payload: e
427
519
  });
428
520
  return s ? { data: s } : { success: !1, error: i };
429
- }, this.config = n, this.api = o, this.contactCtx = c, this.sessionsPollingIntervalSeconds = g, this.registerSessionsRefresherWrapper();
521
+ }, this.config = a, this.api = o, this.contactCtx = c, this.sessionsPollingIntervalSeconds = h, this.registerSessionsRefresherWrapper();
430
522
  }
431
523
  }
432
- class G {
524
+ class K {
433
525
  constructor({
434
- config: n,
526
+ config: a,
435
527
  api: o,
436
528
  sessionCtx: c,
437
- contactCtx: g
529
+ contactCtx: h
438
530
  }) {
439
- this.state = new P({
531
+ this.state = new y({
440
532
  messages: [],
441
533
  isSendingMessage: !1,
442
534
  lastAIResMightSolveUserIssue: !1,
@@ -444,7 +536,7 @@ class G {
444
536
  }), this.sendMessageAbortController = new AbortController(), this.reset = () => {
445
537
  this.sendMessageAbortController.abort("Resetting chat"), this.state.reset();
446
538
  }, this.sendMessage = async (e) => {
447
- var t, s, i, r, a, h, l, p, v, m;
539
+ var t, s, i, r, n, d, l, m, S, x;
448
540
  try {
449
541
  if (!e.content.trim() && (!e.attachments || e.attachments.length === 0)) {
450
542
  console.warn(
@@ -452,32 +544,32 @@ class G {
452
544
  );
453
545
  return;
454
546
  }
455
- const w = this.state.get().isSendingMessage, b = ((t = this.sessionCtx.sessionState.get().session) == null ? void 0 : t.assignee.kind) === "ai", f = this.state.get().messages, S = f.length > 0 ? f[f.length - 1] : void 0;
547
+ const w = this.state.get().isSendingMessage, b = ((t = this.sessionCtx.sessionState.get().session) == null ? void 0 : t.assignee.kind) === "ai", f = this.state.get().messages, C = f.length > 0 ? f[f.length - 1] : void 0;
456
548
  if (b && w || // If last message is from user, then bot response did not arrive yet
457
- b && (S == null ? void 0 : S.type) === "FROM_USER") {
549
+ b && (C == null ? void 0 : C.type) === "USER") {
458
550
  console.warn("Cannot send messages while awaiting AI response");
459
551
  return;
460
552
  }
461
553
  this.sendMessageAbortController = new AbortController(), this.state.setPartial({ lastAIResMightSolveUserIssue: !1 }), this.state.setPartial({ isSendingMessage: !0 });
462
- const T = this.state.get().messages, E = !((s = this.sessionCtx.sessionState.get().session) != null && s.id) && T.length === 0 && ((i = this.config.advancedInitialMessages) == null ? void 0 : i.some((u) => u.persistent)), R = E ? (this.config.advancedInitialMessages || []).filter((u) => u.persistent).map(
554
+ const A = this.state.get().messages, E = !((s = this.sessionCtx.sessionState.get().session) != null && s.id) && A.length === 0 && ((i = this.config.advancedInitialMessages) == null ? void 0 : i.some((u) => u.persistent)), M = E ? (this.config.advancedInitialMessages || []).filter((u) => u.persistent).map(
463
555
  (u) => ({
464
- id: k(),
556
+ id: P(),
465
557
  component: "bot_message",
466
- type: "FROM_BOT",
558
+ type: "AI",
467
559
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
468
560
  data: {
469
561
  message: u.message
470
562
  }
471
563
  })
472
- ) : [], y = this.toUserMessage(
564
+ ) : [], k = this.toUserMessage(
473
565
  e.content.trim(),
474
566
  e.attachments || void 0
475
567
  );
476
568
  if (this.state.setPartial({
477
569
  messages: [
478
- ...R,
479
- ...T,
480
- y
570
+ ...M,
571
+ ...A,
572
+ k
481
573
  ]
482
574
  }), !((r = this.sessionCtx.sessionState.get().session) != null && r.id)) {
483
575
  if (!await this.sessionCtx.createSession()) {
@@ -486,17 +578,17 @@ class G {
486
578
  }
487
579
  this.sessionCtx.refreshSessions();
488
580
  }
489
- const U = (a = this.sessionCtx.sessionState.get().session) == null ? void 0 : a.id;
490
- if (!U) return;
491
- const { data: C } = await this.api.sendMessage(
581
+ const T = (n = this.sessionCtx.sessionState.get().session) == null ? void 0 : n.id;
582
+ if (!T) return;
583
+ const { data: p } = await this.api.sendMessage(
492
584
  {
493
- uuid: y.id,
585
+ uuid: k.id,
494
586
  bot_token: this.config.token,
495
587
  headers: this.config.headers,
496
588
  query_params: this.config.queryParams,
497
589
  body_properties: this.config.bodyProperties,
498
- session_id: U,
499
- content: y.content,
590
+ session_id: T,
591
+ content: k.content,
500
592
  attachments: e.attachments,
501
593
  clientContext: this.config.context,
502
594
  custom_data: {
@@ -505,34 +597,34 @@ class G {
505
597
  },
506
598
  language: this.config.language,
507
599
  exit_mode_prompt: e.exitModePrompt,
508
- initial_messages: E ? R.map((u) => ({
600
+ initial_messages: E ? M.map((u) => ({
509
601
  uuid: u.id,
510
602
  content: u.data.message
511
603
  })) : void 0
512
604
  },
513
605
  this.sendMessageAbortController.signal
514
606
  );
515
- if (C != null && C.success) {
516
- const u = this.toBotMessage(C);
607
+ if (p != null && p.success) {
608
+ const u = this.toBotMessage(p);
517
609
  if (u) {
518
610
  const I = this.state.get().messages;
519
611
  if (!!I.some(
520
612
  (D) => D.id === u.id
521
613
  )) {
522
614
  this.state.setPartial({
523
- lastAIResMightSolveUserIssue: ((h = C.autopilotResponse) == null ? void 0 : h.mightSolveUserIssue) || ((l = C.uiResponse) == null ? void 0 : l.mightSolveUserIssue)
615
+ lastAIResMightSolveUserIssue: ((d = p.autopilotResponse) == null ? void 0 : d.mightSolveUserIssue) || ((l = p.uiResponse) == null ? void 0 : l.mightSolveUserIssue)
524
616
  });
525
617
  return;
526
618
  }
527
619
  this.state.setPartial({
528
620
  messages: [...I, u],
529
- lastAIResMightSolveUserIssue: ((p = C.autopilotResponse) == null ? void 0 : p.mightSolveUserIssue) || ((v = C.uiResponse) == null ? void 0 : v.mightSolveUserIssue)
621
+ lastAIResMightSolveUserIssue: ((m = p.autopilotResponse) == null ? void 0 : m.mightSolveUserIssue) || ((S = p.uiResponse) == null ? void 0 : S.mightSolveUserIssue)
530
622
  });
531
623
  }
532
- C.session && this.sessionCtx.sessionState.setPartial({ session: C.session });
624
+ p.session && this.sessionCtx.sessionState.setPartial({ session: p.session });
533
625
  } else {
534
626
  const u = this.toBotErrorMessage(
535
- ((m = C == null ? void 0 : C.error) == null ? void 0 : m.message) || "Unknown error occurred"
627
+ ((x = p == null ? void 0 : p.error) == null ? void 0 : x.message) || "Unknown error occurred"
536
628
  ), I = this.state.get().messages;
537
629
  this.state.setPartial({
538
630
  messages: [...I, u]
@@ -546,14 +638,14 @@ class G {
546
638
  }, this.toUserMessage = (e, t) => {
547
639
  const s = (() => {
548
640
  const i = this.contactCtx.state.get().extraCollectedData;
549
- return this.state.get().messages.length === 0 && i && Object.keys(i).length > 0 ? `${Object.entries(i).filter(([a, h]) => !!h).map(([a, h]) => `${a}: ${h}`).join(`
641
+ return this.state.get().messages.length === 0 && i && Object.keys(i).length > 0 ? `${Object.entries(i).filter(([n, d]) => !!d).map(([n, d]) => `${n}: ${d}`).join(`
550
642
  `)}
551
643
 
552
644
  ${e}` : e;
553
645
  })();
554
646
  return {
555
- id: k(),
556
- type: "FROM_USER",
647
+ id: P(),
648
+ type: "USER",
557
649
  content: s,
558
650
  deliveredAt: (/* @__PURE__ */ new Date()).toISOString(),
559
651
  attachments: t,
@@ -562,8 +654,8 @@ ${e}` : e;
562
654
  }, this.toBotMessage = (e) => {
563
655
  var t;
564
656
  return e.success && e.autopilotResponse ? {
565
- type: "FROM_BOT",
566
- id: e.autopilotResponse.id || k(),
657
+ type: "AI",
658
+ id: e.autopilotResponse.id || P(),
567
659
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
568
660
  component: "bot_message",
569
661
  agent: this.config.bot ? {
@@ -581,8 +673,8 @@ ${e}` : e;
581
673
  }
582
674
  } : null;
583
675
  }, this.toBotErrorMessage = (e) => ({
584
- type: "FROM_BOT",
585
- id: k(),
676
+ type: "AI",
677
+ id: P(),
586
678
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
587
679
  component: "TEXT",
588
680
  data: {
@@ -590,15 +682,15 @@ ${e}` : e;
590
682
  variant: "error",
591
683
  action: void 0
592
684
  }
593
- }), this.config = n, this.api = o, this.sessionCtx = c, this.contactCtx = g;
685
+ }), this.config = a, this.api = o, this.sessionCtx = c, this.contactCtx = h;
594
686
  }
595
687
  }
596
- class K {
688
+ class z {
597
689
  constructor({
598
- config: n,
690
+ config: a,
599
691
  contactCtx: o,
600
692
  sessionCtx: c,
601
- resetChat: g
693
+ resetChat: h
602
694
  }) {
603
695
  var e;
604
696
  this.registerRoutingListener = () => {
@@ -609,14 +701,14 @@ class K {
609
701
  });
610
702
  }), this.sessionCtx.sessionsState.subscribe(
611
703
  ({ isInitialFetchLoading: t, data: s }) => {
612
- var i, r, a, h;
704
+ var i, r, n, d;
613
705
  if ((i = this.config.router) != null && i.chatScreenOnly && // Do not route to a chat if we are currently inside one already
614
706
  // This also applies to newly created sessions; the new session will be in `sessionState` before it is refreshed and included in `sessionsState`
615
707
  !((r = this.sessionCtx.sessionState.get().session) != null && r.id)) {
616
- const l = (a = s.find((p) => p.isOpened)) == null ? void 0 : a.id;
708
+ const l = (n = s.find((m) => m.isOpened)) == null ? void 0 : n.id;
617
709
  return l ? this.toChatScreen(l) : void 0;
618
710
  }
619
- s.length || ((h = this.config.router) == null ? void 0 : h.goToChatIfNoSessions) !== !1 && !t && this.state.get().screen !== "chat" && this.toChatScreen();
711
+ s.length || ((d = this.config.router) == null ? void 0 : d.goToChatIfNoSessions) !== !1 && !t && this.state.get().screen !== "chat" && this.toChatScreen();
620
712
  }
621
713
  );
622
714
  }, this.toSessionsScreen = () => {
@@ -628,14 +720,14 @@ class K {
628
720
  this.sessionCtx.sessionState.setPartial({ session: s });
629
721
  }
630
722
  this.state.setPartial({ screen: "chat" });
631
- }, this.config = n, this.contactCtx = o, this.sessionCtx = c, this.resetChat = g, this.state = new P({
723
+ }, this.config = a, this.contactCtx = o, this.sessionCtx = c, this.resetChat = h, this.state = new y({
632
724
  screen: this.contactCtx.shouldCollectData() ? "welcome" : (e = this.config.router) != null && e.chatScreenOnly ? "chat" : "sessions"
633
725
  }), this.registerRoutingListener();
634
726
  }
635
727
  }
636
- class Y {
728
+ class j {
637
729
  constructor({
638
- storage: n,
730
+ storage: a,
639
731
  config: o
640
732
  }) {
641
733
  this.KEYS = {
@@ -645,42 +737,47 @@ class Y {
645
737
  await this.storage.set(this.KEYS.contactToken(this.config.token), c);
646
738
  }, this.getContactToken = async () => this.storage.get(this.KEYS.contactToken(this.config.token)), this.setExternalContactId = async (c) => {
647
739
  await this.storage.set(this.KEYS.externalContactId(this.config.token), c);
648
- }, this.getExternalContactId = async () => this.storage.get(this.KEYS.externalContactId(this.config.token)), this.storage = n, this.config = o;
740
+ }, this.getExternalContactId = async () => this.storage.get(this.KEYS.externalContactId(this.config.token)), this.storage = a, this.config = o;
649
741
  }
650
742
  }
651
- const x = class x {
743
+ const v = class v {
652
744
  constructor({
653
- config: n,
745
+ config: a,
654
746
  storage: o,
655
747
  modes: c
656
748
  }) {
657
749
  if (this.modes = [], this.resetChat = () => {
658
750
  this.sessionCtx.reset(), this.messageCtx.reset();
659
- }, !x.pollingIntervalsSeconds)
751
+ }, !v.pollingIntervalsSeconds)
660
752
  throw Error(
661
753
  "Widget polling values are not defined, did you call WidgetCtx.initialize()"
662
754
  );
663
- this.config = n, this.api = new M({ config: n }), this.storageCtx = o ? new Y({ storage: o, config: n }) : void 0, this.modes = c, this.contactCtx = new H({
755
+ this.config = a, this.api = new U({ config: a }), this.storageCtx = o ? new j({ storage: o, config: a }) : void 0, this.modes = c, this.contactCtx = new H({
664
756
  api: this.api,
665
757
  config: this.config,
666
758
  storageCtx: this.storageCtx
667
- }), this.sessionCtx = new X({
759
+ }), this.sessionCtx = new G({
668
760
  config: this.config,
669
761
  api: this.api,
670
762
  contactCtx: this.contactCtx,
671
- sessionsPollingIntervalSeconds: x.pollingIntervalsSeconds.sessions
672
- }), this.messageCtx = new G({
763
+ sessionsPollingIntervalSeconds: v.pollingIntervalsSeconds.sessions
764
+ }), this.messageCtx = new K({
673
765
  config: this.config,
674
766
  api: this.api,
675
767
  sessionCtx: this.sessionCtx,
676
768
  contactCtx: this.contactCtx
677
- }), this.activeSessionPollingCtx = new N({
769
+ }), this.csatCtx = new X({
770
+ config: this.config,
771
+ api: this.api,
772
+ sessionCtx: this.sessionCtx,
773
+ messageCtx: this.messageCtx
774
+ }), this.activeSessionPollingCtx = new Y({
678
775
  api: this.api,
679
776
  config: this.config,
680
777
  sessionCtx: this.sessionCtx,
681
778
  messageCtx: this.messageCtx,
682
- sessionPollingIntervalSeconds: x.pollingIntervalsSeconds.session
683
- }), this.routerCtx = new K({
779
+ sessionPollingIntervalSeconds: v.pollingIntervalsSeconds.session
780
+ }), this.routerCtx = new z({
684
781
  config: this.config,
685
782
  contactCtx: this.contactCtx,
686
783
  sessionCtx: this.sessionCtx,
@@ -688,30 +785,27 @@ const x = class x {
688
785
  });
689
786
  }
690
787
  };
691
- x.pollingIntervalsSeconds = null, x.initialize = async ({
692
- config: n,
788
+ v.pollingIntervalsSeconds = null, v.initialize = async ({
789
+ config: a,
693
790
  storage: o
694
791
  }) => {
695
- var g, e, t;
696
- const c = await new M({
697
- config: n
792
+ var h, e, t;
793
+ const c = await new U({
794
+ config: a
698
795
  }).getExternalWidgetConfig();
699
- return x.pollingIntervalsSeconds = {
700
- session: ((g = c.data) == null ? void 0 : g.sessionPollingIntervalSeconds) || 10,
796
+ return v.pollingIntervalsSeconds = {
797
+ session: ((h = c.data) == null ? void 0 : h.sessionPollingIntervalSeconds) || 10,
701
798
  sessions: ((e = c.data) == null ? void 0 : e.sessionsPollingIntervalSeconds) || 60
702
- }, new x({
703
- config: n,
799
+ }, new v({
800
+ config: a,
704
801
  storage: o,
705
802
  modes: ((t = c.data) == null ? void 0 : t.modes) || []
706
803
  });
707
804
  };
708
- let A = x;
709
- function Q(d, n) {
710
- console.error(`Missing case for ${d} in ${n}`);
711
- }
805
+ let R = v;
712
806
  export {
713
- P as PrimitiveState,
714
- A as WidgetCtx,
715
- Q as isExhaustive
807
+ y as PrimitiveState,
808
+ R as WidgetCtx,
809
+ $ as isExhaustive
716
810
  };
717
811
  //# sourceMappingURL=index.js.map