@opencx/widget 2.4.3 → 2.4.4-rn.0

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 (49) hide show
  1. package/README.md +30 -30
  2. package/dist/basic.cjs +51 -51
  3. package/dist/basic.cjs.map +1 -1
  4. package/dist/basic.js +1983 -1981
  5. package/dist/basic.js.map +1 -1
  6. package/dist/core/client/api.d.ts +36 -6
  7. package/dist/core/client/chat.d.ts +10 -20
  8. package/dist/core/client/config.d.ts +2 -3
  9. package/dist/core/client/contact.d.ts +13 -12
  10. package/dist/core/client/index.d.ts +1 -0
  11. package/dist/core/index.d.ts +0 -1
  12. package/dist/core/platform/index.d.ts +5 -5
  13. package/dist/core/platform/logger.d.ts +14 -0
  14. package/dist/core/platform/storage.d.ts +46 -0
  15. package/dist/core/types/helpers.d.ts +12 -0
  16. package/dist/core/types/index.d.ts +1 -1
  17. package/dist/core/types/messages.d.ts +2 -2
  18. package/dist/core/types/pub-sub.d.ts +24 -8
  19. package/dist/core/types/schemas-v2.d.ts +22 -25
  20. package/dist/{index-Bb4FAD9K.cjs → index-BVoLVQCZ.cjs} +3 -3
  21. package/dist/index-BVoLVQCZ.cjs.map +1 -0
  22. package/dist/{index-D2ByqkLZ.js → index-Cjs7ckCU.js} +92 -87
  23. package/dist/index-Cjs7ckCU.js.map +1 -0
  24. package/dist/index.cjs +1 -1
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.js +705 -343
  27. package/dist/index.js.map +1 -1
  28. package/dist/package.json.d.ts +156 -0
  29. package/dist/react.cjs +1 -1
  30. package/dist/react.cjs.map +1 -1
  31. package/dist/react.js +1 -1
  32. package/dist/react.js.map +1 -1
  33. package/dist/schemas-BBAV6Sd_.js.map +1 -1
  34. package/dist/schemas-wky4fpbc.cjs.map +1 -1
  35. package/dist/style.css +1 -1
  36. package/dist-embed/script.js +5 -5
  37. package/dist-embed/script.js.map +1 -1
  38. package/package.json +3 -1
  39. package/dist/core/client/chat.test.d.ts +0 -1
  40. package/dist/core/client/client.d.ts +0 -9
  41. package/dist/core/client/config.test.d.ts +0 -1
  42. package/dist/core/client/contact.test.d.ts +0 -1
  43. package/dist/index-Bb4FAD9K.cjs.map +0 -1
  44. package/dist/index-D2ByqkLZ.js.map +0 -1
  45. package/dist/react-bindings/context/ChatContext.d.ts +0 -127
  46. package/dist/react-bindings/hooks/useContact.d.ts +0 -9
  47. package/dist/react-bindings/hooks/usePubsub.d.ts +0 -3
  48. package/dist/react-bindings/hooks/useSendMessage.d.ts +0 -6
  49. package/dist/react-bindings/index.d.ts +0 -3
package/dist/index.js CHANGED
@@ -1,248 +1,712 @@
1
- var P = Object.defineProperty;
2
- var w = (t) => {
1
+ var x = Object.defineProperty;
2
+ var N = (t) => {
3
3
  throw TypeError(t);
4
4
  };
5
- var v = (t, e, s) => e in t ? P(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;
6
- var E = (t, e, s) => v(t, typeof e != "symbol" ? e + "" : e, s), O = (t, e, s) => e.has(t) || w("Cannot " + s);
7
- var d = (t, e, s) => (O(t, e, "read from private field"), s ? s.call(t) : e.get(t)), b = (t, e, s) => e.has(t) ? w("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, s), f = (t, e, s, r) => (O(t, e, "write to private field"), r ? r.call(t, s) : e.set(t, s), s);
8
- import { g as y } from "./schemas-BBAV6Sd_.js";
9
- import { A as V, M as K, b as Q, a as W, S as Y, d as Z, e as ee, c as te, f as se, s as re } from "./schemas-BBAV6Sd_.js";
10
- var h;
11
- class S {
5
+ var q = (t, e, s) => e in t ? x(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;
6
+ var h = (t, e, s) => q(t, typeof e != "symbol" ? e + "" : e, s), D = (t, e, s) => e.has(t) || N("Cannot " + s);
7
+ var S = (t, e, s) => (D(t, e, "read from private field"), s ? s.call(t) : e.get(t)), C = (t, e, s) => e.has(t) ? N("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, s), P = (t, e, s, o) => (D(t, e, "write to private field"), o ? o.call(t, s) : e.set(t, s), s);
8
+ import H from "lodash.isequal";
9
+ import { g as L } from "./schemas-BBAV6Sd_.js";
10
+ import { A as ue, M as de, b as fe, a as me, S as ge, d as Se, e as he, c as pe, f as Ee, s as ye } from "./schemas-BBAV6Sd_.js";
11
+ var j = /* @__PURE__ */ ((t) => (t.INIT = "init", t.STATE_CHANGE = "stateChange", t.BEFORE_UPDATE = "beforeUpdate", t.AFTER_UPDATE = "afterUpdate", t.DESTROY = "destroy", t.ERROR = "error", t))(j || {}), y, A;
12
+ class v {
12
13
  constructor(e) {
13
- E(this, "subscribers", /* @__PURE__ */ new Set());
14
- b(this, h);
15
- E(this, "initialState");
16
- f(this, h, e), this.initialState = e;
17
- }
18
- /**
19
- * Subscribe to state changes
20
- * @param callback Function to call when state changes
21
- * @returns Unsubscribe function
22
- */
23
- subscribe(e) {
24
- return this.subscribers.add(e), () => {
14
+ h(this, "subscribers", /* @__PURE__ */ new Set());
15
+ C(this, y);
16
+ h(this, "initialState");
17
+ C(this, A);
18
+ h(this, "lifecycleListeners", /* @__PURE__ */ new Map());
19
+ h(this, "emitLifecycle", (e, s) => {
20
+ const o = this.lifecycleListeners.get(e);
21
+ if (o) {
22
+ const f = {
23
+ type: e,
24
+ timestamp: Date.now(),
25
+ data: s
26
+ };
27
+ o.forEach((a) => a(f));
28
+ }
29
+ });
30
+ /**
31
+ * Subscribe to state changes
32
+ * @param callback Function to call when state changes
33
+ * @returns Unsubscribe function
34
+ */
35
+ h(this, "subscribe", (e) => (this.subscribers.add(e), e(S(this, y)), () => {
25
36
  this.subscribers.delete(e);
26
- };
37
+ }));
38
+ h(this, "onLifecycle", (e, s) => {
39
+ this.lifecycleListeners.has(e) || this.lifecycleListeners.set(e, /* @__PURE__ */ new Set());
40
+ const o = this.lifecycleListeners.get(e);
41
+ return o.add(s), () => {
42
+ o.delete(s), o.size === 0 && this.lifecycleListeners.delete(e);
43
+ };
44
+ });
45
+ /**
46
+ * Get the current state
47
+ */
48
+ h(this, "getState", () => S(this, y));
49
+ /**
50
+ * Set the state and notify subscribers if the state changes
51
+ * @param newState The new state to set
52
+ */
53
+ h(this, "setState", (e) => {
54
+ this.emitLifecycle("beforeUpdate", {
55
+ previousState: S(this, y),
56
+ nextState: e
57
+ }), H(S(this, y), e) || (P(this, y, e), P(this, A, Date.now()), this.emitLifecycle("stateChange", { state: e }), this.subscribers.forEach((s) => {
58
+ try {
59
+ s(e);
60
+ } catch (o) {
61
+ this.emitLifecycle("error", { error: o });
62
+ }
63
+ })), this.emitLifecycle("afterUpdate", { state: e });
64
+ });
65
+ h(this, "setStatePartial", (e) => {
66
+ const s = { ...S(this, y), ...e };
67
+ this.setState(s);
68
+ });
69
+ /**
70
+ * Clear all subscriptions
71
+ */
72
+ h(this, "clear", () => {
73
+ this.emitLifecycle(
74
+ "destroy"
75
+ /* DESTROY */
76
+ ), this.subscribers.clear(), this.lifecycleListeners.clear();
77
+ });
78
+ h(this, "reset", () => {
79
+ this.setState(this.initialState);
80
+ });
81
+ h(this, "lastUpdated", () => S(this, A));
82
+ P(this, y, e), this.initialState = e, P(this, A, Date.now()), this.emitLifecycle("init", { initialState: S(this, y) });
27
83
  }
28
- /**
29
- * Get the current state
30
- */
31
- getState() {
32
- return d(this, h);
84
+ }
85
+ y = new WeakMap(), A = new WeakMap();
86
+ function W(t) {
87
+ return new v(t);
88
+ }
89
+ class M extends Error {
90
+ constructor(e) {
91
+ super(e), this.name = "OpenCXError";
33
92
  }
34
- /**
35
- * Set the state and notify subscribers if the state changes
36
- * @param newState The new state to set
37
- */
38
- setState(e) {
39
- d(this, h) !== e && (f(this, h, e), this.subscribers.forEach((s) => s(e)));
93
+ }
94
+ class Z extends M {
95
+ constructor(e = "Connection failed") {
96
+ super(e), this.name = "ConnectionError";
40
97
  }
41
- setStatePartial(e) {
42
- const s = { ...d(this, h), ...e };
43
- this.setState(s);
98
+ }
99
+ class ee extends M {
100
+ constructor(e = "Authentication failed") {
101
+ super(e), this.name = "AuthenticationError";
44
102
  }
45
- /**
46
- * Clear all subscriptions
47
- */
48
- clear() {
49
- this.subscribers.clear();
103
+ }
104
+ class B extends M {
105
+ constructor(e = "Session error occurred") {
106
+ super(e), this.name = "SessionError";
50
107
  }
51
- reset() {
52
- this.setState(this.initialState);
108
+ }
109
+ class te extends B {
110
+ constructor(e = "Session not defined") {
111
+ super(e), this.name = "SessionNotDefinedError";
53
112
  }
54
- getSnapshot() {
55
- return d(this, h);
113
+ }
114
+ class se extends M {
115
+ constructor(e = "Transport error occurred") {
116
+ super(e), this.name = "TransportError";
56
117
  }
57
- get state() {
58
- return d(this, h);
118
+ }
119
+ class re extends M {
120
+ constructor(e = "File upload failed") {
121
+ super(e), this.name = "FileUploadError";
59
122
  }
60
123
  }
61
- h = new WeakMap();
62
- function $(t) {
63
- return new S(t);
124
+ function T(t) {
125
+ if (!t) return !1;
126
+ try {
127
+ return typeof t.isAvailable == "function" ? t.isAvailable() : !0;
128
+ } catch {
129
+ return !1;
130
+ }
64
131
  }
65
- const I = 1e4, T = 5e3;
66
- function C(t) {
67
- var e, s, r;
132
+ async function O(t, e) {
133
+ try {
134
+ return { success: !0, result: await t() };
135
+ } catch (s) {
136
+ return console.error(e, s), {
137
+ success: !1,
138
+ error: s instanceof Error ? s : new Error(e)
139
+ };
140
+ }
141
+ }
142
+ const R = {
143
+ SESSION: 1e4,
144
+ // every 10 seconds
145
+ MESSAGES: 5e3
146
+ // every 5 seconds
147
+ };
148
+ function k(t) {
149
+ const e = {
150
+ id: t.publicId || L(),
151
+ timestamp: t.sentAt || "",
152
+ attachments: t.attachments || void 0
153
+ };
68
154
  return t.sender.kind === "user" ? {
69
- id: t.publicId || y(),
155
+ ...e,
70
156
  type: "FROM_USER",
71
157
  content: t.content.text || "",
72
- deliveredAt: ((e = t.sentAt) == null ? void 0 : e.toISOString()) || null,
73
- attachments: t.attachments || void 0,
74
- timestamp: (s = t.sentAt) == null ? void 0 : s.toISOString()
158
+ deliveredAt: t.sentAt || ""
75
159
  } : {
76
- id: t.publicId || y(),
160
+ ...e,
77
161
  type: "FROM_BOT",
78
- component: t.type,
79
- data: {
80
- text: t.content.text
162
+ component: "TEXT",
163
+ agent: {
164
+ id: null,
165
+ name: t.sender.name || "",
166
+ is_ai: t.sender.kind === "ai",
167
+ profile_picture: t.sender.avatar
81
168
  },
82
- timestamp: (r = t.sentAt) == null ? void 0 : r.toISOString(),
83
- attachments: t.attachments || void 0
169
+ data: {
170
+ message: t.content.text
171
+ }
84
172
  };
85
173
  }
86
- function A(t, e, s) {
87
- const r = [];
88
- return r.push(
89
- setInterval(async () => {
90
- const n = e.getState();
91
- if (n != null && n.id)
92
- try {
93
- const a = await t.getSession(n.id);
94
- a && e.setState(a);
95
- } catch (a) {
96
- console.error("Error polling session:", a);
97
- }
98
- }, I)
99
- ), r.push(
100
- setInterval(async () => {
101
- const n = e.getState();
102
- if (n != null && n.id)
103
- try {
104
- const a = await t.getSessionHistory(n.id);
105
- if (a) {
106
- const l = a.map(C);
107
- s.setStatePartial({
108
- messages: l,
109
- lastUpdated: Date.now()
110
- });
111
- }
112
- } catch (a) {
113
- console.error("Error polling messages:", a);
174
+ function G(t, e, s) {
175
+ async function o(c) {
176
+ const l = e.getState().messages;
177
+ if (l.length === 0) {
178
+ s == null || s.debug("No messages yet, fetching all history", { sessionId: c.id });
179
+ const g = await t.getSessionHistory(c.id, "");
180
+ g && g.length > 0 && e.setStatePartial({
181
+ messages: g.map(k)
182
+ });
183
+ return;
184
+ }
185
+ const d = l[l.length - 1], n = new Date(d.timestamp);
186
+ n.setSeconds(n.getSeconds() + 1);
187
+ const i = n.toISOString();
188
+ s == null || s.debug("Fetching history messages after timestamp", {
189
+ sessionId: c.id,
190
+ lastMessageTimestamp: i,
191
+ currentMessageCount: l.length
192
+ });
193
+ const E = await t.getSessionHistory(c.id, i);
194
+ if (E && E.length > 0) {
195
+ const g = E.map(k).filter((p) => !l.some((b) => b.id === p.id));
196
+ g.length > 0 && (s == null || s.debug("Adding new messages to state", {
197
+ count: g.length,
198
+ messageIds: g.map((p) => p.id),
199
+ messageTypes: g.map((p) => p.type)
200
+ }), e.setStatePartial({
201
+ messages: [...l, ...g]
202
+ }));
203
+ }
204
+ }
205
+ function f(c, l) {
206
+ return {
207
+ id: L(),
208
+ type: "FROM_USER",
209
+ content: c,
210
+ deliveredAt: (/* @__PURE__ */ new Date()).toISOString(),
211
+ attachments: l,
212
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
213
+ };
214
+ }
215
+ function a(c) {
216
+ if (c.success && c.autopilotResponse)
217
+ return {
218
+ type: "FROM_BOT",
219
+ id: c.autopilotResponse.id || L(),
220
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
221
+ component: "TEXT",
222
+ data: {
223
+ message: c.autopilotResponse.value.content
114
224
  }
115
- }, T)
116
- ), () => r.forEach(clearInterval);
225
+ };
226
+ if (c.success && c.uiResponse) {
227
+ const l = c.uiResponse.value;
228
+ return {
229
+ type: "FROM_BOT",
230
+ id: L(),
231
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
232
+ component: l.name,
233
+ data: l.request_response
234
+ };
235
+ }
236
+ return null;
237
+ }
238
+ function r(c) {
239
+ return {
240
+ type: "FROM_BOT",
241
+ id: L(),
242
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
243
+ component: "TEXT",
244
+ data: {
245
+ message: c,
246
+ variant: "error"
247
+ }
248
+ };
249
+ }
250
+ return {
251
+ fetchHistoryMessages: o,
252
+ addUserMessage: f,
253
+ addBotMessage: a,
254
+ addErrorMessage: r
255
+ };
117
256
  }
118
- function L(t) {
119
- const e = new S({
120
- lastUpdated: null,
121
- messages: [],
122
- keyboard: null
123
- }), s = new S(null);
124
- let r = null;
125
- async function n() {
126
- const o = await t.api.createSession();
127
- return s.setState(o), r || (r = A(t.api, s, e)), o;
128
- }
129
- async function a() {
130
- var i;
131
- const o = s.getState();
132
- if (o != null && o.id)
257
+ function J(t, e, s, o, f, a) {
258
+ var F, U;
259
+ const r = (F = a.platform) == null ? void 0 : F.logger;
260
+ let c = null;
261
+ const l = (U = a.platform) == null ? void 0 : U.storage, d = `${f.getConfig().user.external_id}:${f.getConfig().token}:session`, n = a.config.getSettings().persistSession;
262
+ async function i() {
263
+ if (l)
133
264
  try {
134
- r && (r(), r = null), s.setState(null), e.setState({
135
- lastUpdated: null,
136
- messages: [],
137
- keyboard: null
138
- }), (i = t.onSessionDestroy) == null || i.call(t);
265
+ r == null || r.debug("Attempting to restore session from storage");
266
+ const u = await l.getItem(d);
267
+ if (u) {
268
+ const m = JSON.parse(u);
269
+ r == null || r.info("Session restored from storage", { sessionId: m.id }), e.setState(m), await o.fetchHistoryMessages(m), g();
270
+ }
139
271
  } catch (u) {
140
- throw console.error("Error clearing session:", u), u;
272
+ r == null || r.error("Error restoring session from storage:", u);
141
273
  }
142
274
  }
143
- function l() {
144
- r && (r(), r = null), e.setState({
145
- lastUpdated: null,
146
- messages: [],
147
- keyboard: null
148
- }), s.setState(null), e.clear(), s.clear();
275
+ function E() {
276
+ l && (r == null || r.debug("Setting up session persistence"), e.subscribe(async (u) => {
277
+ try {
278
+ u ? (await l.setItem(d, JSON.stringify(u)), r == null || r.debug("Session persisted to storage", { sessionId: u.id })) : (await l.removeItem(d), r == null || r.debug("Session removed from storage"));
279
+ } catch (m) {
280
+ r == null || r.error("Error persisting session:", m), s.setStatePartial({
281
+ error: {
282
+ hasError: !0,
283
+ message: m instanceof Error ? m.message : "Failed to persist session",
284
+ code: "SESSION_PERSISTENCE_FAILED"
285
+ }
286
+ });
287
+ }
288
+ }));
149
289
  }
150
- return {
151
- chatState: e,
152
- sessionState: s,
153
- sendMessage: async (o) => {
154
- const i = s.getState();
155
- if (!(i != null && i.id))
156
- throw new Error("No active session");
157
- const u = {
158
- ...o,
159
- session_id: i.id
290
+ function g() {
291
+ if (c) return;
292
+ r == null || r.debug("Starting polling");
293
+ const u = [];
294
+ u.push(
295
+ setInterval(async () => {
296
+ const m = e.getState();
297
+ if (m != null && m.id)
298
+ try {
299
+ const w = await t.getSession(m.id);
300
+ w && e.setState(w);
301
+ } catch (w) {
302
+ r == null || r.error("Error polling session:", w);
303
+ }
304
+ }, R.SESSION)
305
+ ), u.push(
306
+ setInterval(async () => {
307
+ const m = e.getState();
308
+ if (m != null && m.id)
309
+ try {
310
+ await o.fetchHistoryMessages(m);
311
+ } catch (w) {
312
+ r == null || r.error("Error polling messages:", w);
313
+ }
314
+ }, R.MESSAGES)
315
+ ), c = () => {
316
+ r == null || r.debug("Stopping polling"), u.forEach(clearInterval);
317
+ };
318
+ }
319
+ async function p() {
320
+ try {
321
+ r == null || r.info("Creating new session"), s.setStatePartial({
322
+ loading: { isLoading: !0, reason: "creating_session" },
323
+ error: { hasError: !1 }
324
+ });
325
+ const u = await t.createSession();
326
+ return r == null || r.info("Session created successfully", { sessionId: u.id }), e.setState(u), g(), u;
327
+ } catch (u) {
328
+ r == null || r.error("Failed to create session:", u);
329
+ const m = {
330
+ hasError: !0,
331
+ message: u instanceof Error ? u.message : "Failed to create session",
332
+ code: "SESSION_CREATION_FAILED"
160
333
  };
334
+ return s.setStatePartial({ error: m }), null;
335
+ } finally {
336
+ s.setStatePartial({
337
+ loading: { isLoading: !1, reason: null }
338
+ });
339
+ }
340
+ }
341
+ async function b() {
342
+ var m;
343
+ const u = e.getState();
344
+ if (u != null && u.id)
161
345
  try {
162
- e.setStatePartial({
163
- messages: [
164
- ...e.getState().messages,
165
- {
166
- id: o.id || y(),
167
- type: "FROM_USER",
168
- content: o.content.text,
169
- deliveredAt: (/* @__PURE__ */ new Date()).toISOString(),
170
- attachments: o.attachments,
171
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
172
- }
173
- ]
174
- }), await t.api.handleMessage(u);
175
- } catch (m) {
176
- throw console.error("Error sending message:", m), m;
346
+ c && (c(), c = null), e.setState(null), n && l && T(l) && l.removeItem(d), s.setState({
347
+ messages: [],
348
+ keyboard: null,
349
+ loading: { isLoading: !1 },
350
+ error: { hasError: !1 }
351
+ }), (m = a.onSessionDestroy) == null || m.call(a);
352
+ } catch (w) {
353
+ console.error("Error clearing session:", w), s.setStatePartial({
354
+ error: {
355
+ hasError: !0,
356
+ message: w instanceof Error ? w.message : "Failed to clear session",
357
+ code: "SESSION_CLEAR_FAILED"
358
+ }
359
+ });
177
360
  }
178
- },
179
- createSession: n,
180
- clearSession: a,
181
- cleanup: l
361
+ }
362
+ function _() {
363
+ try {
364
+ c && (c(), c = null), n && l && T(l) && l.removeItem(d), s.setState({
365
+ messages: [],
366
+ keyboard: null,
367
+ loading: { isLoading: !1 },
368
+ error: { hasError: !1 }
369
+ }), e.setState(null), s.clear(), e.clear();
370
+ } catch (u) {
371
+ console.error("Error in cleanup:", u), s.setStatePartial({
372
+ error: {
373
+ hasError: !0,
374
+ message: u instanceof Error ? u.message : "Failed to cleanup",
375
+ code: "SESSION_CLEAR_FAILED"
376
+ }
377
+ });
378
+ }
379
+ }
380
+ return n && T(l) && (i(), E()), {
381
+ createSession: p,
382
+ clearSession: b,
383
+ cleanup: _,
384
+ startPolling: g
182
385
  };
183
386
  }
184
- function N(t) {
185
- var l;
186
- const e = `${t.botToken}:contact:${(l = t.user) == null ? void 0 : l.external_id}`;
187
- let s = null;
188
- if (t.platform.storage) {
189
- const c = t.platform.storage.getItem(e);
190
- if (c)
191
- try {
192
- s = JSON.parse(c);
193
- } catch (o) {
194
- console.error("Error parsing stored contact:", o);
387
+ function ae(t) {
388
+ var c;
389
+ const e = (c = t.platform) == null ? void 0 : c.logger;
390
+ e == null || e.info("Initializing chat");
391
+ const s = new v({
392
+ messages: [],
393
+ keyboard: null,
394
+ loading: { isLoading: !1 },
395
+ error: { hasError: !1 }
396
+ }), o = new v(null), f = G(t.api, s, e), a = J(
397
+ t.api,
398
+ o,
399
+ s,
400
+ f,
401
+ t.config,
402
+ t
403
+ );
404
+ async function r(l) {
405
+ var n;
406
+ let d = o.getState();
407
+ if (!(d != null && d.id) && (e == null || e.debug("No active session, creating new session"), d = await a.createSession(), !d))
408
+ return !1;
409
+ try {
410
+ e == null || e.debug("Sending message", { sessionId: d.id }), s.setStatePartial({
411
+ loading: { isLoading: !0, reason: "sending_message" },
412
+ error: { hasError: !1 }
413
+ });
414
+ const i = f.addUserMessage(l.content, l.attachments || void 0), E = s.getState().messages;
415
+ s.setStatePartial({
416
+ messages: [...E, i]
417
+ });
418
+ const g = t.config.getConfig(), p = await t.api.handleMessage({
419
+ bot_token: g.token,
420
+ headers: g.headers,
421
+ query_params: g.queryParams,
422
+ session_id: d.id,
423
+ ...l
424
+ });
425
+ if (p.success) {
426
+ e == null || e.debug("Message sent successfully");
427
+ const b = f.addBotMessage(p);
428
+ if (b) {
429
+ const _ = s.getState().messages;
430
+ s.setStatePartial({
431
+ messages: [..._, b]
432
+ });
433
+ }
434
+ } else {
435
+ e == null || e.warn("Message send failed", p.error);
436
+ const b = f.addErrorMessage(((n = p.error) == null ? void 0 : n.message) || "Unknown error occurred"), _ = s.getState().messages;
437
+ s.setStatePartial({
438
+ messages: [..._, b]
439
+ });
195
440
  }
441
+ return !0;
442
+ } catch (i) {
443
+ return e == null || e.error("Error sending message:", i), s.setStatePartial({
444
+ error: {
445
+ hasError: !0,
446
+ message: i instanceof Error ? i.message : "Failed to send message",
447
+ code: "MESSAGE_SEND_FAILED"
448
+ }
449
+ }), !1;
450
+ } finally {
451
+ s.setStatePartial({
452
+ loading: { isLoading: !1, reason: null }
453
+ });
454
+ }
196
455
  }
197
- const r = new S(s);
198
- t.platform.storage && r.subscribe((c) => {
199
- var o, i;
200
- c ? (o = t.platform.storage) == null || o.setItem(e, JSON.stringify(c)) : (i = t.platform.storage) == null || i.removeItem(e);
456
+ return {
457
+ chatState: s,
458
+ sessionState: o,
459
+ sendMessage: r,
460
+ createSession: a.createSession,
461
+ clearSession: a.clearSession,
462
+ cleanup: a.cleanup
463
+ };
464
+ }
465
+ function ne(t) {
466
+ const e = t.config.getConfig();
467
+ t.config.getConfig;
468
+ const s = `${e.token}:contact:${e.user.external_id}`, o = T(t.platform.storage) ? t.platform.storage : void 0;
469
+ let f = null;
470
+ o && O(
471
+ async () => {
472
+ const n = await o.getItem(s);
473
+ return n ? JSON.parse(n) : null;
474
+ },
475
+ "Error loading contact from storage"
476
+ ).then((n) => {
477
+ n.success && (f = n.result);
201
478
  });
202
- function n() {
203
- const c = r.getState();
204
- return !(c != null && c.id) && t.collectUserData ? {
479
+ const a = new v({
480
+ contact: f,
481
+ loading: { isLoading: !1 },
482
+ error: { hasError: !1 }
483
+ });
484
+ T(o) && a.subscribe((n) => {
485
+ O(
486
+ async () => {
487
+ n.contact ? await o.setItem(s, JSON.stringify(n.contact)) : o.removeItem(s);
488
+ },
489
+ "Error persisting contact state"
490
+ ).then((i) => {
491
+ i.success || a.setStatePartial({
492
+ error: {
493
+ hasError: !0,
494
+ message: i.error.message,
495
+ code: "CONTACT_PERSISTENCE_FAILED"
496
+ }
497
+ });
498
+ });
499
+ });
500
+ async function r() {
501
+ try {
502
+ if (a.setStatePartial({
503
+ loading: { isLoading: !0, reason: "loading_contact" },
504
+ error: { hasError: !1 }
505
+ }), o) {
506
+ const n = await O(
507
+ async () => {
508
+ const i = await o.getItem(s);
509
+ return i ? JSON.parse(i) : null;
510
+ },
511
+ "Error loading contact"
512
+ );
513
+ if (!n.success)
514
+ throw n.error;
515
+ return a.setStatePartial({
516
+ contact: n.result,
517
+ error: { hasError: !1 }
518
+ }), n.result;
519
+ }
520
+ return a.getState().contact;
521
+ } catch (n) {
522
+ return a.setStatePartial({
523
+ error: {
524
+ hasError: !0,
525
+ message: n instanceof Error ? n.message : "Failed to load contact",
526
+ code: "CONTACT_LOAD_FAILED"
527
+ }
528
+ }), null;
529
+ } finally {
530
+ a.setStatePartial({
531
+ loading: { isLoading: !1, reason: null }
532
+ });
533
+ }
534
+ }
535
+ async function c(n) {
536
+ try {
537
+ a.setStatePartial({
538
+ loading: { isLoading: !0, reason: "saving_contact" },
539
+ error: { hasError: !1 }
540
+ });
541
+ const i = a.getState().contact, E = {
542
+ id: n.id || (i == null ? void 0 : i.id) || "",
543
+ name: n.name ?? (i == null ? void 0 : i.name) ?? null,
544
+ created_at: n.created_at || (i == null ? void 0 : i.created_at) || (/* @__PURE__ */ new Date()).toISOString(),
545
+ avatar_url: n.avatar_url ?? (i == null ? void 0 : i.avatar_url) ?? null,
546
+ email: n.email ?? (i == null ? void 0 : i.email) ?? null
547
+ };
548
+ if (T(o)) {
549
+ const g = await O(
550
+ () => o.setItem(s, JSON.stringify(E)),
551
+ "Error saving contact"
552
+ );
553
+ if (!g.success)
554
+ throw g.error;
555
+ }
556
+ return a.setStatePartial({
557
+ contact: E,
558
+ error: { hasError: !1 }
559
+ }), E;
560
+ } catch (i) {
561
+ return a.setStatePartial({
562
+ error: {
563
+ hasError: !0,
564
+ message: i instanceof Error ? i.message : "Failed to save contact",
565
+ code: "CONTACT_SAVE_FAILED"
566
+ }
567
+ }), null;
568
+ } finally {
569
+ a.setStatePartial({
570
+ loading: { isLoading: !1, reason: null }
571
+ });
572
+ }
573
+ }
574
+ function l() {
575
+ var i;
576
+ return !((i = a.getState().contact) != null && i.id) && e.collectUserData ? {
205
577
  should: !0,
206
578
  reason: "No contact id and collectUserData is true"
207
579
  } : {
208
580
  should: !1
209
581
  };
210
582
  }
211
- function a() {
212
- r.clear(), r.setState(null);
583
+ async function d() {
584
+ try {
585
+ if (a.setStatePartial({
586
+ loading: { isLoading: !0, reason: "cleaning_up" },
587
+ error: { hasError: !1 }
588
+ }), o) {
589
+ const n = await O(
590
+ () => o.removeItem(s),
591
+ "Error removing contact data"
592
+ );
593
+ if (!n.success)
594
+ throw n.error;
595
+ }
596
+ a.setState({
597
+ contact: null,
598
+ loading: { isLoading: !1 },
599
+ error: { hasError: !1 }
600
+ }), a.clear();
601
+ } catch (n) {
602
+ console.error("Error cleaning up contact:", n), a.setStatePartial({
603
+ error: {
604
+ hasError: !0,
605
+ message: n instanceof Error ? n.message : "Failed to cleanup contact data",
606
+ code: "CONTACT_CLEANUP_FAILED"
607
+ }
608
+ });
609
+ } finally {
610
+ a.setStatePartial({
611
+ loading: { isLoading: !1, reason: null }
612
+ });
613
+ }
213
614
  }
214
615
  return {
215
- shouldCollectData: n,
216
- cleanup: a,
217
- contactState: r
616
+ contactState: a,
617
+ shouldCollectData: l,
618
+ loadContact: r,
619
+ saveContact: c,
620
+ cleanup: d
621
+ };
622
+ }
623
+ const X = {
624
+ messageArrived: "https://cloud.opencopilot.so/sfx/notification3.mp3"
625
+ }, $ = {
626
+ primaryColor: "hsl(211,65%,59%)",
627
+ triggerOffset: "20px"
628
+ }, z = 1e3 * 3;
629
+ function oe(t) {
630
+ var s, o, f, a, r, c, l, d, n;
631
+ if (!t.token)
632
+ throw new Error("Token is required");
633
+ if (t.pollingInterval && t.pollingInterval < z)
634
+ throw new Error("Polling interval must be at least 3 seconds");
635
+ const e = {
636
+ ...t,
637
+ collectUserData: t.collectUserData ?? !1,
638
+ apiUrl: t.apiUrl ?? "https://api-v2.opencopilot.so/backend",
639
+ socketUrl: t.socketUrl ?? "https://api-v2.opencopilot.so",
640
+ pollingInterval: t.pollingInterval ?? 3e3,
641
+ headers: t.headers ?? {},
642
+ queryParams: t.queryParams ?? {},
643
+ pathParams: t.pathParams ?? {},
644
+ bot: {
645
+ name: ((s = t.bot) == null ? void 0 : s.name) ?? "Bot",
646
+ avatarUrl: (o = t.bot) == null ? void 0 : o.avatarUrl,
647
+ id: ((f = t.bot) == null ? void 0 : f.id) ?? null,
648
+ is_ai: ((a = t.bot) == null ? void 0 : a.is_ai) ?? !0
649
+ },
650
+ contactToken: t.contactToken,
651
+ debug: t.debug ?? !1,
652
+ language: t.language ?? "en",
653
+ user: t.user ?? {},
654
+ soundEffectFiles: {
655
+ messageArrived: ((r = t.soundEffectFiles) == null ? void 0 : r.messageArrived) ?? X.messageArrived
656
+ },
657
+ theme: {
658
+ primaryColor: ((c = t.theme) == null ? void 0 : c.primaryColor) ?? $.primaryColor,
659
+ triggerOffset: ((l = t.theme) == null ? void 0 : l.triggerOffset) ?? $.triggerOffset
660
+ },
661
+ settings: {
662
+ persistSession: ((d = t.settings) == null ? void 0 : d.persistSession) ?? !1,
663
+ useSoundEffects: ((n = t.settings) == null ? void 0 : n.useSoundEffects) ?? !1
664
+ }
665
+ };
666
+ return {
667
+ getConfig: () => e,
668
+ getApiConfig: () => ({
669
+ apiUrl: e.apiUrl,
670
+ token: e.token,
671
+ headers: e.headers,
672
+ queryParams: e.queryParams,
673
+ pathParams: e.pathParams
674
+ }),
675
+ getBotConfig: () => e.bot,
676
+ getThemeConfig: () => e.theme,
677
+ getSettings: () => e.settings,
678
+ getSoundEffects: () => e.soundEffectFiles,
679
+ getUser: () => e.user,
680
+ getLanguage: () => e.language,
681
+ getDebugMode: () => e.debug
218
682
  };
219
683
  }
220
- function k(t = {}) {
221
- const e = [], s = [], r = [], n = async (a, l = {}) => {
684
+ function V(t = {}) {
685
+ const e = [], s = [], o = [], f = async (a, r = {}) => {
222
686
  let c = {
223
687
  ...t,
224
- ...l,
688
+ ...r,
225
689
  headers: {
226
690
  ...t.headers,
227
- ...l.headers
691
+ ...r.headers
228
692
  }
229
693
  };
230
694
  try {
231
- for (const m of e)
232
- c = await m(c);
233
- const o = c.params ? "?" + new URLSearchParams(c.params).toString() : "", i = c.baseURL ? `${c.baseURL}${a}${o}`.replace(/([^:]\/)\/+/g, "$1") : `${a}${o}`;
234
- let u = await fetch(i, c);
235
- for (const m of s)
236
- u = await m(u);
237
- return u;
238
- } catch (o) {
239
- let i = o;
240
- for (const u of r)
241
- i = await u(i);
242
- throw i;
695
+ for (const i of e)
696
+ c = await i(c);
697
+ const l = c.params ? "?" + new URLSearchParams(c.params).toString() : "", d = c.baseURL ? `${c.baseURL}${a}${l}`.replace(/([^:]\/)\/+/g, "$1") : `${a}${l}`;
698
+ let n = await fetch(d, c);
699
+ for (const i of s)
700
+ n = await i(n);
701
+ return n;
702
+ } catch (l) {
703
+ let d = l;
704
+ for (const n of o)
705
+ d = await n(d);
706
+ throw d;
243
707
  }
244
708
  };
245
- return n.interceptors = {
709
+ return f.interceptors = {
246
710
  request: {
247
711
  use: (a) => (e.push(a), e.length - 1),
248
712
  eject: (a) => {
@@ -250,200 +714,98 @@ function k(t = {}) {
250
714
  }
251
715
  },
252
716
  response: {
253
- use: (a, l) => (s.push(a), l && r.push(l), s.length - 1),
717
+ use: (a, r) => (s.push(a), r && o.push(r), s.length - 1),
254
718
  eject: (a) => {
255
- s.splice(a, 1), r.splice(a, 1);
719
+ s.splice(a, 1), o.splice(a, 1);
256
720
  }
257
721
  }
258
- }, n;
722
+ }, f;
259
723
  }
260
- var g;
261
- class _ {
724
+ var I;
725
+ class ie {
262
726
  constructor(e) {
263
- b(this, g);
727
+ C(this, I);
264
728
  this.options = e;
265
- const s = this.options.coreOptions.user, r = {
729
+ const s = this.options.config.user, o = {
266
730
  claim: "",
267
731
  value: ""
268
732
  };
269
- s != null && s.email ? (r.claim = "email", r.value = s.email) : s != null && s.phone && (r.claim = "phone", r.value = s.phone);
270
- const n = {
271
- "X-Bot-Token": this.options.token,
272
- "X-Consumer-Id": `${r.claim}:${r.value}`
733
+ s != null && s.email ? (o.claim = "email", o.value = s.email) : s != null && s.phone && (o.claim = "phone", o.value = s.phone);
734
+ const f = {
735
+ "X-Bot-Token": this.options.config.token,
736
+ "X-Consumer-Id": `${o.claim}:${o.value}`,
737
+ "Content-Type": "application/json",
738
+ Accept: "application/json"
273
739
  };
274
- this.options.coreOptions.contactToken && (n.Authorization = `Bearer ${this.options.coreOptions.contactToken}`), f(this, g, k({
275
- baseURL: `${this.options.apiUrl}/widget/v2`,
276
- headers: n
740
+ this.options.config.contactToken && (f.Authorization = `Bearer ${this.options.config.contactToken}`), P(this, I, V({
741
+ baseURL: `${this.options.config.apiUrl}/widget/v2`,
742
+ headers: f
277
743
  }));
278
744
  }
279
745
  async me() {
280
- return (await d(this, g).call(this, "/me")).json();
746
+ return (await S(this, I).call(this, "/me")).json();
281
747
  }
282
748
  async widgetPrelude() {
283
- return (await d(this, g).call(this, "/prelude")).json();
749
+ return (await S(this, I).call(this, "/prelude")).json();
284
750
  }
285
751
  async handleMessage(e) {
286
- return (await d(this, g).call(this, "/chat/send", {
752
+ return (await S(this, I).call(this, "/chat/send", {
287
753
  method: "POST",
288
754
  body: JSON.stringify(e)
289
755
  })).json();
290
756
  }
291
757
  async getSessionHistory(e, s) {
292
- const r = new URLSearchParams({
758
+ const o = new URLSearchParams({
293
759
  lastMessageTimestamp: s || ""
294
- }), n = `/session/history/${e}?${r.toString()}`;
295
- return (await d(this, g).call(this, n, {
760
+ }), f = `/session/history/${e}?${o.toString()}`;
761
+ return (await S(this, I).call(this, f, {
296
762
  method: "GET"
297
763
  })).json();
298
764
  }
299
765
  async createSession() {
300
- return (await d(this, g).call(this, "/create-session", {
766
+ return (await S(this, I).call(this, "/create-session", {
301
767
  method: "POST"
302
768
  })).json();
303
769
  }
304
770
  async getSession(e) {
305
- return (await d(this, g).call(this, `/session/${e}`, {
771
+ return (await S(this, I).call(this, `/session/${e}`, {
306
772
  method: "GET"
307
773
  })).json();
308
774
  }
309
775
  async createContact(e) {
310
- return (await d(this, g).call(this, "/contact/upsert", {
776
+ return (await S(this, I).call(this, "/contact/upsert", {
311
777
  method: "POST",
312
778
  body: JSON.stringify(e)
313
779
  })).json();
314
780
  }
315
781
  }
316
- g = new WeakMap();
317
- class p extends Error {
318
- constructor(e) {
319
- super(e), this.name = "OpenCXError";
320
- }
321
- }
322
- class R extends p {
323
- constructor(e = "Connection failed") {
324
- super(e), this.name = "ConnectionError";
325
- }
326
- }
327
- class j extends p {
328
- constructor(e = "Authentication failed") {
329
- super(e), this.name = "AuthenticationError";
330
- }
331
- }
332
- class x extends p {
333
- constructor(e = "Session error occurred") {
334
- super(e), this.name = "SessionError";
335
- }
336
- }
337
- class q extends x {
338
- constructor(e = "Session not defined") {
339
- super(e), this.name = "SessionNotDefinedError";
340
- }
341
- }
342
- class B extends p {
343
- constructor(e = "Transport error occurred") {
344
- super(e), this.name = "TransportError";
345
- }
346
- }
347
- class H extends p {
348
- constructor(e = "File upload failed") {
349
- super(e), this.name = "FileUploadError";
350
- }
351
- }
352
- function G() {
353
- return {
354
- env: {
355
- platform: typeof window < "u" ? "browser" : "server"
356
- },
357
- date: {
358
- now: () => Date.now(),
359
- toISOString: (e) => new Date(e).toISOString()
360
- }
361
- };
362
- }
363
- const D = {
364
- messageArrived: "https://cloud.opencopilot.so/sfx/notification3.mp3"
365
- }, U = {
366
- primaryColor: "hsl(211,65%,59%)",
367
- triggerOffset: "20px"
368
- };
369
- function X(t) {
370
- var s, r, n, a, l, c, o, i, u;
371
- const e = {
372
- ...t,
373
- apiUrl: t.apiUrl ?? "https://api-v2.opencopilot.so/backend",
374
- socketUrl: t.socketUrl ?? "https://api-v2.opencopilot.so",
375
- transport: t.transport ?? "socket",
376
- pollingInterval: t.pollingInterval ?? 3e3,
377
- headers: {
378
- ...t.headers ?? {},
379
- "X-Bot-Token": t.token
380
- },
381
- queryParams: t.queryParams ?? {},
382
- pathParams: t.pathParams ?? {},
383
- bot: {
384
- name: ((s = t.bot) == null ? void 0 : s.name) ?? "Bot",
385
- avatarUrl: (r = t.bot) == null ? void 0 : r.avatarUrl,
386
- id: ((n = t.bot) == null ? void 0 : n.id) ?? null,
387
- is_ai: ((a = t.bot) == null ? void 0 : a.is_ai) ?? !0
388
- },
389
- contactToken: t.contactToken,
390
- debug: t.debug ?? !1,
391
- language: t.language ?? "en",
392
- user: t.user ?? {},
393
- soundEffectFiles: {
394
- messageArrived: ((l = t.soundEffectFiles) == null ? void 0 : l.messageArrived) ?? D.messageArrived
395
- },
396
- theme: {
397
- primaryColor: ((c = t.theme) == null ? void 0 : c.primaryColor) ?? U.primaryColor,
398
- triggerOffset: ((o = t.theme) == null ? void 0 : o.triggerOffset) ?? U.triggerOffset
399
- },
400
- settings: {
401
- persistSession: ((i = t.settings) == null ? void 0 : i.persistSession) ?? !1,
402
- useSoundEffects: ((u = t.settings) == null ? void 0 : u.useSoundEffects) ?? !1
403
- }
404
- };
405
- return {
406
- getConfig: () => e,
407
- getApiConfig: () => ({
408
- apiUrl: e.apiUrl,
409
- token: e.token,
410
- headers: e.headers,
411
- queryParams: e.queryParams,
412
- pathParams: e.pathParams
413
- }),
414
- getBotConfig: () => e.bot,
415
- getThemeConfig: () => e.theme,
416
- getSettings: () => e.settings,
417
- getSoundEffects: () => e.soundEffectFiles,
418
- getUser: () => e.user,
419
- getLanguage: () => e.language,
420
- getDebugMode: () => e.debug
421
- };
422
- }
782
+ I = new WeakMap();
423
783
  export {
424
- V as AIClosureType,
425
- _ as ApiCaller,
426
- j as AuthenticationError,
427
- R as ConnectionError,
428
- H as FileUploadError,
429
- K as MessageTypeEnum,
430
- p as OpenCXError,
431
- S as PubSub,
432
- Q as SentimentEnum,
433
- W as SessionChannel,
434
- x as SessionError,
435
- q as SessionNotDefinedError,
436
- Y as SessionStatus,
437
- B as TransportError,
438
- Z as chatAttachmentSchema,
439
- ee as chatHistoryMessageSchema,
440
- te as chatSessionSchema,
441
- se as consumerSchema,
442
- L as createChat,
443
- X as createConfig,
444
- N as createContact,
445
- G as createDefaultPlatform,
446
- $ as createPubSub,
447
- re as structuredSocketMessageSchema
784
+ ue as AIClosureType,
785
+ ie as ApiCaller,
786
+ ee as AuthenticationError,
787
+ Z as ConnectionError,
788
+ re as FileUploadError,
789
+ j as LifecycleEvent,
790
+ de as MessageTypeEnum,
791
+ M as OpenCXError,
792
+ v as PubSub,
793
+ fe as SentimentEnum,
794
+ me as SessionChannel,
795
+ B as SessionError,
796
+ te as SessionNotDefinedError,
797
+ ge as SessionStatus,
798
+ se as TransportError,
799
+ Se as chatAttachmentSchema,
800
+ he as chatHistoryMessageSchema,
801
+ pe as chatSessionSchema,
802
+ Ee as consumerSchema,
803
+ ae as createChat,
804
+ oe as createConfig,
805
+ ne as createContact,
806
+ W as createPubSub,
807
+ T as isStorageAvailable,
808
+ O as safeStorageOperation,
809
+ ye as structuredSocketMessageSchema
448
810
  };
449
811
  //# sourceMappingURL=index.js.map