@opencx/widget 3.0.100 → 4.0.18

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