@opencx/widget-core 4.0.9 → 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 +307 -195
  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 +44 -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 +44 -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 +259 -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 +4 -1
  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 M from "openapi-fetch";
2
- import O from "lodash.isequal";
3
- import { v4 as U } from "uuid";
4
- const F = (d) => {
5
- console.log(d.error);
6
- }, D = (d) => {
7
- const n = M({
8
- baseUrl: d.baseUrl
1
+ import F from "openapi-fetch";
2
+ import L from "lodash.isequal";
3
+ import { v4 as O } from "uuid";
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 || F
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 T {
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 T {
27
27
  }, this.createOpenAPIClient = ({
28
28
  baseUrl: t,
29
29
  headers: s
30
- }) => D({
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,55 +74,58 @@ class T {
74
74
  file: t,
75
75
  abortSignal: s,
76
76
  onProgress: i
77
- }) => new Promise((r, a) => {
78
- var m;
79
- const h = new FormData();
80
- h.append("file", t);
77
+ }) => new Promise((r, n) => {
78
+ var b;
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
- l.upload.addEventListener("progress", (u) => {
89
- if (u.lengthComputable && i) {
90
- const x = Math.round(u.loaded / u.total * 100);
91
- i(x);
88
+ l.upload.addEventListener("progress", (f) => {
89
+ if (f.lengthComputable && i) {
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)
95
95
  try {
96
- const u = JSON.parse(l.responseText);
97
- r(u);
98
- } catch (u) {
99
- a(new Error(`Failed to parse response: ${u}`));
96
+ const f = JSON.parse(l.responseText);
97
+ r(f);
98
+ } catch (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: C } = this.constructClientOptions(this.userToken), S = `${C}/backend/widget/v2/upload`;
109
- l.open("POST", S), l.setRequestHeader("X-Bot-Token", this.config.token), this.userToken ?? ((m = this.config.user) == null ? void 0 : m.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
- O(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 R {
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 R {
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 _(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 L {
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 R(), 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, C = a.history.map(this.mapHistoryToMessage).filter(
206
- (p) => !l.some((S) => S.id === p.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, ...C]
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 L {
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,67 +242,117 @@ class L {
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 = _(() => 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
- class B {
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, C, p, S, b, m, u;
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 x = await ((r = this.storageCtx) == null ? void 0 : r.getContactToken());
289
- x && await this.setUnverifiedContact(x);
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 x = await ((l = this.storageCtx) == null ? void 0 : l.getContactToken());
294
- if (x) {
295
- await this.setUnverifiedContact(x);
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: (p = (C = this.config.user) == null ? void 0 : C.data) == null ? void 0 : p.email,
301
- non_verified_name: ((b = (S = this.config.user) == null ? void 0 : S.data) == null ? void 0 : b.name) || "Anonymous",
302
- non_verified_custom_data: (u = (m = this.config.user) == null ? void 0 : m.data) == null ? void 0 : u.customData
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",
355
+ non_verified_custom_data: (f = (b = this.config.user) == null ? void 0 : b.data) == null ? void 0 : f.customData
303
356
  });
304
357
  }
305
358
  }, this.createUnverifiedContact = async (e, t) => {
@@ -315,14 +368,14 @@ class B {
315
368
  this.state.setPartial({ isCreatingUnverifiedContact: !1 });
316
369
  }
317
370
  }, this.setUnverifiedContact = async (e) => {
318
- var i, r, a, h;
319
- const t = await ((i = this.storageCtx) == null ? void 0 : i.getExternalContactId()), s = ((r = this.config.user) == null ? void 0 : r.externalId) || t || U();
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,
371
+ var i, r, n, d;
372
+ const t = await ((i = this.storageCtx) == null ? void 0 : i.getExternalContactId()), s = ((r = this.config.user) == null ? void 0 : r.externalId) || t || O();
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 B {
330
383
  }), this.autoCreateUnverifiedUserIfNotExists();
331
384
  }
332
385
  }
333
- function I() {
334
- return U();
386
+ function P() {
387
+ return O();
388
+ }
389
+ class X {
390
+ constructor({
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
+ }
335
427
  }
336
- class $ {
428
+ class G {
337
429
  constructor({
338
- config: n,
430
+ config: a,
339
431
  api: o,
340
432
  contactCtx: c,
341
- sessionsPollingIntervalSeconds: g
433
+ sessionsPollingIntervalSeconds: h
342
434
  }) {
343
- this.sessionsRefresher = new R(), 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 $ {
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 $ {
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 $ {
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 q {
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 q {
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, C;
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,37 +544,51 @@ class q {
452
544
  );
453
545
  return;
454
546
  }
455
- const p = this.state.get().isSendingMessage, S = ((t = this.sessionCtx.sessionState.get().session) == null ? void 0 : t.assignee.kind) === "ai", b = this.state.get().messages, m = b.length > 0 ? b[b.length - 1] : void 0;
456
- if (S && p || // If last message is from user, then bot response did not arrive yet
457
- S && (m == null ? void 0 : m.type) === "FROM_USER") {
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;
548
+ if (b && w || // If last message is from user, then bot response did not arrive yet
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 u = this.toUserMessage(
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(
555
+ (u) => ({
556
+ id: P(),
557
+ component: "bot_message",
558
+ type: "AI",
559
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
560
+ data: {
561
+ message: u.message
562
+ }
563
+ })
564
+ ) : [], k = this.toUserMessage(
463
565
  e.content.trim(),
464
566
  e.attachments || void 0
465
- ), x = this.state.get().messages;
567
+ );
466
568
  if (this.state.setPartial({
467
- messages: [...x, u]
468
- }), !((s = this.sessionCtx.sessionState.get().session) != null && s.id)) {
569
+ messages: [
570
+ ...M,
571
+ ...A,
572
+ k
573
+ ]
574
+ }), !((r = this.sessionCtx.sessionState.get().session) != null && r.id)) {
469
575
  if (!await this.sessionCtx.createSession()) {
470
576
  console.error("Failed to create session");
471
577
  return;
472
578
  }
473
579
  this.sessionCtx.refreshSessions();
474
580
  }
475
- const y = (i = this.sessionCtx.sessionState.get().session) == null ? void 0 : i.id;
476
- if (!y) return;
477
- const { data: f } = 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(
478
584
  {
479
- uuid: u.id,
585
+ uuid: k.id,
480
586
  bot_token: this.config.token,
481
587
  headers: this.config.headers,
482
588
  query_params: this.config.queryParams,
483
589
  body_properties: this.config.bodyProperties,
484
- session_id: y,
485
- content: u.content,
590
+ session_id: T,
591
+ content: k.content,
486
592
  attachments: e.attachments,
487
593
  clientContext: this.config.context,
488
594
  custom_data: {
@@ -490,52 +596,56 @@ class q {
490
596
  ...e.customData || {}
491
597
  },
492
598
  language: this.config.language,
493
- exit_mode_prompt: e.exitModePrompt
599
+ exit_mode_prompt: e.exitModePrompt,
600
+ initial_messages: E ? M.map((u) => ({
601
+ uuid: u.id,
602
+ content: u.data.message
603
+ })) : void 0
494
604
  },
495
605
  this.sendMessageAbortController.signal
496
606
  );
497
- if (f != null && f.success) {
498
- const w = this.toBotMessage(f);
499
- if (w) {
500
- const k = this.state.get().messages;
501
- if (!!k.some(
502
- (A) => A.id === w.id
607
+ if (p != null && p.success) {
608
+ const u = this.toBotMessage(p);
609
+ if (u) {
610
+ const I = this.state.get().messages;
611
+ if (!!I.some(
612
+ (D) => D.id === u.id
503
613
  )) {
504
614
  this.state.setPartial({
505
- lastAIResMightSolveUserIssue: ((r = f.autopilotResponse) == null ? void 0 : r.mightSolveUserIssue) || ((a = f.uiResponse) == null ? void 0 : a.mightSolveUserIssue)
615
+ lastAIResMightSolveUserIssue: ((d = p.autopilotResponse) == null ? void 0 : d.mightSolveUserIssue) || ((l = p.uiResponse) == null ? void 0 : l.mightSolveUserIssue)
506
616
  });
507
617
  return;
508
618
  }
509
619
  this.state.setPartial({
510
- messages: [...k, w],
511
- lastAIResMightSolveUserIssue: ((h = f.autopilotResponse) == null ? void 0 : h.mightSolveUserIssue) || ((l = f.uiResponse) == null ? void 0 : l.mightSolveUserIssue)
620
+ messages: [...I, u],
621
+ lastAIResMightSolveUserIssue: ((m = p.autopilotResponse) == null ? void 0 : m.mightSolveUserIssue) || ((S = p.uiResponse) == null ? void 0 : S.mightSolveUserIssue)
512
622
  });
513
623
  }
514
- f.session && this.sessionCtx.sessionState.setPartial({ session: f.session });
624
+ p.session && this.sessionCtx.sessionState.setPartial({ session: p.session });
515
625
  } else {
516
- const w = this.toBotErrorMessage(
517
- ((C = f == null ? void 0 : f.error) == null ? void 0 : C.message) || "Unknown error occurred"
518
- ), k = this.state.get().messages;
626
+ const u = this.toBotErrorMessage(
627
+ ((x = p == null ? void 0 : p.error) == null ? void 0 : x.message) || "Unknown error occurred"
628
+ ), I = this.state.get().messages;
519
629
  this.state.setPartial({
520
- messages: [...k, w]
630
+ messages: [...I, u]
521
631
  });
522
632
  }
523
- } catch (p) {
524
- this.sendMessageAbortController.signal.aborted || console.error("Failed to send message:", p);
633
+ } catch (w) {
634
+ this.sendMessageAbortController.signal.aborted || console.error("Failed to send message:", w);
525
635
  } finally {
526
636
  this.state.setPartial({ isSendingMessage: !1 });
527
637
  }
528
638
  }, this.toUserMessage = (e, t) => {
529
639
  const s = (() => {
530
640
  const i = this.contactCtx.state.get().extraCollectedData;
531
- 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(`
532
642
  `)}
533
643
 
534
644
  ${e}` : e;
535
645
  })();
536
646
  return {
537
- id: I(),
538
- type: "FROM_USER",
647
+ id: P(),
648
+ type: "USER",
539
649
  content: s,
540
650
  deliveredAt: (/* @__PURE__ */ new Date()).toISOString(),
541
651
  attachments: t,
@@ -544,8 +654,8 @@ ${e}` : e;
544
654
  }, this.toBotMessage = (e) => {
545
655
  var t;
546
656
  return e.success && e.autopilotResponse ? {
547
- type: "FROM_BOT",
548
- id: e.autopilotResponse.id || I(),
657
+ type: "AI",
658
+ id: e.autopilotResponse.id || P(),
549
659
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
550
660
  component: "bot_message",
551
661
  agent: this.config.bot ? {
@@ -563,8 +673,8 @@ ${e}` : e;
563
673
  }
564
674
  } : null;
565
675
  }, this.toBotErrorMessage = (e) => ({
566
- type: "FROM_BOT",
567
- id: I(),
676
+ type: "AI",
677
+ id: P(),
568
678
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
569
679
  component: "TEXT",
570
680
  data: {
@@ -572,15 +682,15 @@ ${e}` : e;
572
682
  variant: "error",
573
683
  action: void 0
574
684
  }
575
- }), 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;
576
686
  }
577
687
  }
578
- class N {
688
+ class z {
579
689
  constructor({
580
- config: n,
690
+ config: a,
581
691
  contactCtx: o,
582
692
  sessionCtx: c,
583
- resetChat: g
693
+ resetChat: h
584
694
  }) {
585
695
  var e;
586
696
  this.registerRoutingListener = () => {
@@ -591,14 +701,14 @@ class N {
591
701
  });
592
702
  }), this.sessionCtx.sessionsState.subscribe(
593
703
  ({ isInitialFetchLoading: t, data: s }) => {
594
- var i, r, a, h;
704
+ var i, r, n, d;
595
705
  if ((i = this.config.router) != null && i.chatScreenOnly && // Do not route to a chat if we are currently inside one already
596
706
  // This also applies to newly created sessions; the new session will be in `sessionState` before it is refreshed and included in `sessionsState`
597
707
  !((r = this.sessionCtx.sessionState.get().session) != null && r.id)) {
598
- const l = (a = s.find((C) => C.isOpened)) == null ? void 0 : a.id;
708
+ const l = (n = s.find((m) => m.isOpened)) == null ? void 0 : n.id;
599
709
  return l ? this.toChatScreen(l) : void 0;
600
710
  }
601
- 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();
602
712
  }
603
713
  );
604
714
  }, this.toSessionsScreen = () => {
@@ -610,14 +720,14 @@ class N {
610
720
  this.sessionCtx.sessionState.setPartial({ session: s });
611
721
  }
612
722
  this.state.setPartial({ screen: "chat" });
613
- }, 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({
614
724
  screen: this.contactCtx.shouldCollectData() ? "welcome" : (e = this.config.router) != null && e.chatScreenOnly ? "chat" : "sessions"
615
725
  }), this.registerRoutingListener();
616
726
  }
617
727
  }
618
- class H {
728
+ class j {
619
729
  constructor({
620
- storage: n,
730
+ storage: a,
621
731
  config: o
622
732
  }) {
623
733
  this.KEYS = {
@@ -627,12 +737,12 @@ class H {
627
737
  await this.storage.set(this.KEYS.contactToken(this.config.token), c);
628
738
  }, this.getContactToken = async () => this.storage.get(this.KEYS.contactToken(this.config.token)), this.setExternalContactId = async (c) => {
629
739
  await this.storage.set(this.KEYS.externalContactId(this.config.token), c);
630
- }, 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;
631
741
  }
632
742
  }
633
743
  const v = class v {
634
744
  constructor({
635
- config: n,
745
+ config: a,
636
746
  storage: o,
637
747
  modes: c
638
748
  }) {
@@ -642,27 +752,32 @@ const v = class v {
642
752
  throw Error(
643
753
  "Widget polling values are not defined, did you call WidgetCtx.initialize()"
644
754
  );
645
- this.config = n, this.api = new T({ config: n }), this.storageCtx = o ? new H({ storage: o, config: n }) : void 0, this.modes = c, this.contactCtx = new B({
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({
646
756
  api: this.api,
647
757
  config: this.config,
648
758
  storageCtx: this.storageCtx
649
- }), this.sessionCtx = new $({
759
+ }), this.sessionCtx = new G({
650
760
  config: this.config,
651
761
  api: this.api,
652
762
  contactCtx: this.contactCtx,
653
763
  sessionsPollingIntervalSeconds: v.pollingIntervalsSeconds.sessions
654
- }), this.messageCtx = new q({
764
+ }), this.messageCtx = new K({
655
765
  config: this.config,
656
766
  api: this.api,
657
767
  sessionCtx: this.sessionCtx,
658
768
  contactCtx: this.contactCtx
659
- }), this.activeSessionPollingCtx = new L({
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({
660
775
  api: this.api,
661
776
  config: this.config,
662
777
  sessionCtx: this.sessionCtx,
663
778
  messageCtx: this.messageCtx,
664
779
  sessionPollingIntervalSeconds: v.pollingIntervalsSeconds.session
665
- }), this.routerCtx = new N({
780
+ }), this.routerCtx = new z({
666
781
  config: this.config,
667
782
  contactCtx: this.contactCtx,
668
783
  sessionCtx: this.sessionCtx,
@@ -671,29 +786,26 @@ const v = class v {
671
786
  }
672
787
  };
673
788
  v.pollingIntervalsSeconds = null, v.initialize = async ({
674
- config: n,
789
+ config: a,
675
790
  storage: o
676
791
  }) => {
677
- var g, e, t;
678
- const c = await new T({
679
- config: n
792
+ var h, e, t;
793
+ const c = await new U({
794
+ config: a
680
795
  }).getExternalWidgetConfig();
681
796
  return v.pollingIntervalsSeconds = {
682
- session: ((g = c.data) == null ? void 0 : g.sessionPollingIntervalSeconds) || 10,
797
+ session: ((h = c.data) == null ? void 0 : h.sessionPollingIntervalSeconds) || 10,
683
798
  sessions: ((e = c.data) == null ? void 0 : e.sessionsPollingIntervalSeconds) || 60
684
799
  }, new v({
685
- config: n,
800
+ config: a,
686
801
  storage: o,
687
802
  modes: ((t = c.data) == null ? void 0 : t.modes) || []
688
803
  });
689
804
  };
690
- let E = v;
691
- function z(d, n) {
692
- console.error(`Missing case for ${d} in ${n}`);
693
- }
805
+ let R = v;
694
806
  export {
695
- P as PrimitiveState,
696
- E as WidgetCtx,
697
- z as isExhaustive
807
+ y as PrimitiveState,
808
+ R as WidgetCtx,
809
+ $ as isExhaustive
698
810
  };
699
811
  //# sourceMappingURL=index.js.map