@opencx/widget 2.6.3 → 3.0.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 (155) hide show
  1. package/dist/basic.cjs +89 -89
  2. package/dist/basic.cjs.map +1 -1
  3. package/dist/basic.d.ts +1 -1
  4. package/dist/basic.js +34083 -34125
  5. package/dist/basic.js.map +1 -1
  6. package/dist/index.cjs +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +3 -22
  9. package/dist/react.cjs +1 -1
  10. package/dist/react.cjs.map +1 -1
  11. package/dist/react.d.ts +1 -1
  12. package/dist/react.js +20 -10
  13. package/dist/react.js.map +1 -1
  14. package/dist/src/designs/react/basic/index.d.ts +10 -0
  15. package/dist/src/designs/{basic → react/basic}/utils/group-messages-by-type.d.ts +1 -1
  16. package/dist/src/{@components → designs/react/components}/BotOrAgentMessage.d.ts +1 -1
  17. package/dist/src/{@components → designs/react/components}/BotOrAgentMessageGroup.d.ts +2 -2
  18. package/dist/src/designs/react/components/BotOrAgentMessageWrapper.d.ts +7 -0
  19. package/dist/src/{@components → designs/react/components}/Fallback.component.d.ts +2 -2
  20. package/dist/src/{components → designs/react/components}/RenderFile.d.ts +2 -2
  21. package/dist/src/{@components → designs/react/components}/Text.component.d.ts +1 -1
  22. package/dist/src/{components → designs/react/components}/UserMessageGroup.d.ts +1 -1
  23. package/dist/src/{components → designs/react/components}/VoteButtons.d.ts +1 -1
  24. package/dist/src/designs/{constants.d.ts → react/constants.d.ts} +2 -4
  25. package/dist/src/designs/react/hooks/useLocale.d.ts +6 -0
  26. package/dist/src/{index.d.ts → designs/react/index.d.ts} +2 -2
  27. package/dist/src/designs/translation/ar.locale.d.ts +2 -0
  28. package/dist/src/designs/translation/de.locale.d.ts +2 -0
  29. package/dist/src/designs/translation/en.locale.d.ts +2 -0
  30. package/dist/src/designs/translation/fr.locale.d.ts +2 -0
  31. package/dist/src/designs/translation/index.d.ts +14 -0
  32. package/dist/src/designs/translation/nl.locale.d.ts +2 -0
  33. package/dist/src/designs/translation/pt.locale.d.ts +2 -0
  34. package/dist/src/designs/translation/translation.types.d.ts +4 -0
  35. package/dist/{core/client → src/headless/core}/api.d.ts +49 -103
  36. package/dist/src/headless/core/context/contact.d.ts +25 -0
  37. package/dist/src/headless/core/context/message.d.ts +40 -0
  38. package/dist/src/headless/core/context/session.d.ts +74 -0
  39. package/dist/src/headless/core/context/widget.d.ts +16 -0
  40. package/dist/src/headless/core/index.d.ts +7 -0
  41. package/dist/src/headless/core/types/WidgetConfig.d.ts +34 -0
  42. package/dist/src/headless/core/types/agent-or-bot.d.ts +6 -0
  43. package/dist/src/headless/core/types/helpers.d.ts +4 -0
  44. package/dist/{core → src/headless/core}/types/messages.d.ts +11 -31
  45. package/dist/src/headless/core/types/schemas.d.ts +9 -0
  46. package/dist/src/headless/core/utils/Poller.d.ts +12 -0
  47. package/dist/{core/types/pub-sub.d.ts → src/headless/core/utils/PubSub.d.ts} +6 -9
  48. package/dist/{react-web/core-integration/components.d.ts → src/headless/react/ComponentRegistry.d.ts} +1 -1
  49. package/dist/src/headless/react/WidgetProvider.d.ts +17 -0
  50. package/dist/src/headless/react/hooks/useConfig.d.ts +1 -0
  51. package/dist/src/headless/react/hooks/useContact.d.ts +10 -0
  52. package/dist/src/headless/react/hooks/useIsAwaitingBotReply.d.ts +3 -0
  53. package/dist/src/headless/react/hooks/useMessages.d.ts +8 -0
  54. package/dist/{react-web/core-integration → src/headless/react}/hooks/usePreludeData.d.ts +2 -2
  55. package/dist/{react-web/core-integration → src/headless/react}/hooks/usePubsub.d.ts +1 -1
  56. package/dist/src/headless/react/hooks/useSession.d.ts +6 -0
  57. package/dist/{react-web/core-integration → src/headless/react}/hooks/useVote.d.ts +2 -2
  58. package/dist/src/headless/react/index.d.ts +11 -0
  59. package/dist/src/headless/react/types/components.d.ts +15 -0
  60. package/dist/style.css +1 -1
  61. package/dist/useUploadFiles-BZa0DENN.cjs +18 -0
  62. package/dist/useUploadFiles-BZa0DENN.cjs.map +1 -0
  63. package/dist/useUploadFiles-BaCcqTwX.js +1336 -0
  64. package/dist/useUploadFiles-BaCcqTwX.js.map +1 -0
  65. package/dist/widget-BlvH6dre.cjs +2 -0
  66. package/dist/widget-BlvH6dre.cjs.map +1 -0
  67. package/dist/widget-DbgWez1r.js +514 -0
  68. package/dist/widget-DbgWez1r.js.map +1 -0
  69. package/dist-embed/script.js +120 -140
  70. package/dist-embed/script.js.map +1 -1
  71. package/package.json +9 -4
  72. package/dist/api-CAm3rFZk.js +0 -1070
  73. package/dist/api-CAm3rFZk.js.map +0 -1
  74. package/dist/api-oIDR-KZx.cjs +0 -2
  75. package/dist/api-oIDR-KZx.cjs.map +0 -1
  76. package/dist/core/client/chat.d.ts +0 -101
  77. package/dist/core/client/config.d.ts +0 -43
  78. package/dist/core/client/contact.d.ts +0 -29
  79. package/dist/core/client/index.d.ts +0 -4
  80. package/dist/core/errors/index.d.ts +0 -27
  81. package/dist/core/index.d.ts +0 -9
  82. package/dist/core/platform/audio.d.ts +0 -38
  83. package/dist/core/platform/index.d.ts +0 -15
  84. package/dist/core/platform/logger.d.ts +0 -14
  85. package/dist/core/platform/storage.d.ts +0 -52
  86. package/dist/core/tests/platform/logger.test.d.ts +0 -1
  87. package/dist/core/tests/platform/storage.test.d.ts +0 -1
  88. package/dist/core/tests/test-utils.d.ts +0 -2
  89. package/dist/core/tests/types/pub-sub.test.d.ts +0 -1
  90. package/dist/core/types/contact.d.ts +0 -2
  91. package/dist/core/types/helpers.d.ts +0 -20
  92. package/dist/core/types/index.d.ts +0 -52
  93. package/dist/core/types/prelude.d.ts +0 -14
  94. package/dist/core/types/schemas-v2.d.ts +0 -10
  95. package/dist/index-CSptf_Dw.cjs +0 -18
  96. package/dist/index-CSptf_Dw.cjs.map +0 -1
  97. package/dist/index-cUkS-tdv.js +0 -1232
  98. package/dist/index-cUkS-tdv.js.map +0 -1
  99. package/dist/react-web/core-integration/ChatProvider.d.ts +0 -107
  100. package/dist/react-web/core-integration/hooks/useChatMessages.d.ts +0 -70
  101. package/dist/react-web/core-integration/hooks/useChatSession.d.ts +0 -83
  102. package/dist/react-web/core-integration/hooks/useConfig.d.ts +0 -1
  103. package/dist/react-web/core-integration/hooks/useContact.d.ts +0 -17
  104. package/dist/react-web/core-integration/hooks/useLocale.d.ts +0 -4
  105. package/dist/react-web/core-integration/hooks.d.ts +0 -9
  106. package/dist/react-web/core-integration/index.d.ts +0 -2
  107. package/dist/react-web/core-integration/locales/ar.locale.d.ts +0 -2
  108. package/dist/react-web/core-integration/locales/de.locale.d.ts +0 -2
  109. package/dist/react-web/core-integration/locales/en.locale.d.ts +0 -55
  110. package/dist/react-web/core-integration/locales/fr.locale.d.ts +0 -2
  111. package/dist/react-web/core-integration/locales/helper.d.ts +0 -65
  112. package/dist/react-web/core-integration/locales/index.d.ts +0 -3
  113. package/dist/react-web/core-integration/locales/nl.locale.d.ts +0 -2
  114. package/dist/react-web/core-integration/locales/pt.locale.d.ts +0 -2
  115. package/dist/react-web/hooks/useScrollTo.d.ts +0 -2
  116. package/dist/react-web/index.d.ts +0 -4
  117. package/dist/react-web/types/components.d.ts +0 -13
  118. package/dist/react-web/types/index.d.ts +0 -8
  119. package/dist/react-web/types/options.d.ts +0 -17
  120. package/dist/src/@components/BotOrAgentMessageWrapper.d.ts +0 -9
  121. package/dist/src/@components/ChatEvent.component.d.ts +0 -9
  122. package/dist/src/@components/index.d.ts +0 -6
  123. package/dist/src/designs/basic/index.d.ts +0 -8
  124. /package/dist/src/designs/{basic → react/basic}/WidgetPopoverTrigger.d.ts +0 -0
  125. /package/dist/src/designs/{basic → react/basic}/screens/chat-screen/ChatFooter.d.ts +0 -0
  126. /package/dist/src/designs/{basic → react/basic}/screens/chat-screen/ChatHeader.d.ts +0 -0
  127. /package/dist/src/designs/{basic → react/basic}/screens/chat-screen/ChatMain.d.ts +0 -0
  128. /package/dist/src/designs/{basic → react/basic}/screens/chat-screen/ChatScreen.d.ts +0 -0
  129. /package/dist/src/designs/{basic → react/basic}/screens/root-screen.d.ts +0 -0
  130. /package/dist/src/designs/{basic → react/basic}/screens/welcome-screen/WelcomeScreen.d.ts +0 -0
  131. /package/dist/{core/tests/client/integration-perisitance.test.d.ts → src/designs/react/basic/widget-interaction-tests/widget.test.d.ts} +0 -0
  132. /package/dist/src/{@components → designs/react/components}/Loading.component.d.ts +0 -0
  133. /package/dist/src/{@components → designs/react/components}/OpenLogoSvg.d.ts +0 -0
  134. /package/dist/src/{components → designs/react/components}/keyboard.d.ts +0 -0
  135. /package/dist/src/{components → designs/react/components/lib}/MotionDiv.d.ts +0 -0
  136. /package/dist/src/{components → designs/react/components/lib}/avatar.d.ts +0 -0
  137. /package/dist/src/{components → designs/react/components/lib}/button.d.ts +0 -0
  138. /package/dist/src/{components → designs/react/components/lib}/dialog.d.ts +0 -0
  139. /package/dist/src/{components → designs/react/components/lib}/dropdown-menu.d.ts +0 -0
  140. /package/dist/src/{components → designs/react/components/lib}/input.d.ts +0 -0
  141. /package/dist/src/{components → designs/react/components/lib}/popover.d.ts +0 -0
  142. /package/dist/src/{components → designs/react/components/lib}/skeleton.d.ts +0 -0
  143. /package/dist/src/{components → designs/react/components/lib}/switch.d.ts +0 -0
  144. /package/dist/src/{components → designs/react/components/lib}/tooltip.d.ts +0 -0
  145. /package/dist/src/{utils.d.ts → designs/react/components/lib/utils/cn.d.ts} +0 -0
  146. /package/dist/src/{components → designs/react/components/lib}/wobble.d.ts +0 -0
  147. /package/dist/src/{@components → designs/react/components}/markdown.d.ts +0 -0
  148. /package/dist/{react-web → src/designs/react}/hooks/useWidgetContentHeight.d.ts +0 -0
  149. /package/dist/src/{render.d.ts → designs/react/render.d.ts} +0 -0
  150. /package/dist/{core → src/headless/core}/sdk/index.d.ts +0 -0
  151. /package/dist/{core/tests/client/integration.test.d.ts → src/headless/core/utils/PubSub.test.d.ts} +0 -0
  152. /package/dist/{core/utils/genUuid.d.ts → src/headless/core/utils/uuid.d.ts} +0 -0
  153. /package/dist/{react-web/core-integration → src/headless/react}/hooks/useUploadFiles.d.ts +0 -0
  154. /package/dist/{react-web → src/headless/react}/utils/create-safe-context.d.ts +0 -0
  155. /package/dist/{core/tests/platform/audio.test.d.ts → vitest/setup.d.ts} +0 -0
@@ -0,0 +1,514 @@
1
+ var x = Object.defineProperty;
2
+ var A = (a) => {
3
+ throw TypeError(a);
4
+ };
5
+ var O = (a, t, e) => t in a ? x(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
6
+ var s = (a, t, e) => O(a, typeof t != "symbol" ? t + "" : t, e), U = (a, t, e) => t.has(a) || A("Cannot " + e);
7
+ var c = (a, t, e) => (U(a, t, "read from private field"), e ? e.call(a) : t.get(a)), S = (a, t, e) => t.has(a) ? A("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(a) : t.set(a, e), p = (a, t, e, i) => (U(a, t, "write to private field"), i ? i.call(a, e) : t.set(a, e), e);
8
+ import R from "axios";
9
+ import E from "openapi-fetch";
10
+ import F from "lodash.isequal";
11
+ import { v4 as L } from "uuid";
12
+ const D = (a) => {
13
+ console.log(a.error);
14
+ }, I = (a) => {
15
+ const t = E({
16
+ baseUrl: a.baseUrl
17
+ }), e = {
18
+ onRequest: a.onRequest,
19
+ onResponse: a.onResponse,
20
+ onError: a.onError || D
21
+ };
22
+ return t.use(e), t;
23
+ };
24
+ class B {
25
+ constructor({
26
+ config: t
27
+ }) {
28
+ s(this, "client");
29
+ s(this, "uploadFileClient");
30
+ s(this, "config");
31
+ s(this, "constructClientOptions", (t) => {
32
+ const e = this.config.apiUrl || "https://api.open.cx", i = {
33
+ "X-Bot-Token": this.config.token,
34
+ "Content-Type": "application/json",
35
+ Accept: "application/json",
36
+ Authorization: t ? `Bearer ${t}` : void 0
37
+ };
38
+ return { baseUrl: e, headers: i };
39
+ });
40
+ s(this, "createOpenAPIClient", ({
41
+ baseUrl: t,
42
+ headers: e
43
+ }) => I({
44
+ baseUrl: t,
45
+ onRequest: ({ request: i }) => {
46
+ Object.entries(e).forEach(([n, r]) => {
47
+ r && i.headers.set(n, r);
48
+ });
49
+ }
50
+ }));
51
+ s(this, "createAxiosUploadClient", ({
52
+ baseUrl: t,
53
+ headers: e
54
+ }) => R.create({
55
+ baseURL: `${t}/backend/widget/v2/upload`,
56
+ headers: e
57
+ }));
58
+ s(this, "setAuthToken", (t) => {
59
+ const { baseUrl: e, headers: i } = this.constructClientOptions(t);
60
+ this.client = this.createOpenAPIClient({ baseUrl: e, headers: i }), this.uploadFileClient = this.createAxiosUploadClient({ baseUrl: e, headers: i });
61
+ });
62
+ s(this, "widgetPrelude", async () => await this.client.GET("/backend/widget/v2/prelude", {
63
+ params: { header: { "X-Bot-Token": this.config.token } }
64
+ }));
65
+ s(this, "sendMessage", async (t, e) => await this.client.POST("/backend/widget/v2/chat/send", {
66
+ body: t,
67
+ signal: e
68
+ }));
69
+ s(this, "getSessionHistory", async ({
70
+ sessionId: t,
71
+ lastMessageTimestamp: e,
72
+ abortSignal: i
73
+ }) => {
74
+ const n = e ? { lastMessageTimestamp: e } : void 0;
75
+ return await this.client.GET(
76
+ "/backend/widget/v2/session/history/{sessionId}",
77
+ { params: { path: { sessionId: t }, query: n }, signal: i }
78
+ );
79
+ });
80
+ s(this, "createUnverifiedContact", async (t) => await this.client.POST(
81
+ "/backend/widget/v2/contact/create-unverified",
82
+ {
83
+ params: { header: { "x-bot-token": this.config.token } },
84
+ body: t
85
+ }
86
+ ));
87
+ s(this, "createSession", async () => await this.client.POST("/backend/widget/v2/create-session"));
88
+ s(this, "getSession", async ({
89
+ sessionId: t,
90
+ abortSignal: e
91
+ }) => await this.client.GET("/backend/widget/v2/session/{sessionId}", {
92
+ params: { path: { sessionId: t } },
93
+ signal: e
94
+ }));
95
+ s(this, "uploadFile", async (t, e = {}) => {
96
+ const i = new FormData();
97
+ i.append("file", t.file);
98
+ const { data: n } = await this.uploadFileClient.post("", i, {
99
+ headers: {
100
+ "Content-Type": "multipart/form-data"
101
+ },
102
+ ...e
103
+ });
104
+ return n;
105
+ });
106
+ s(this, "vote", async (t) => await this.client.POST("/backend/widget/v2/chat/vote", { body: t }));
107
+ this.config = t;
108
+ const { baseUrl: e, headers: i } = this.constructClientOptions(
109
+ t.contactToken
110
+ );
111
+ this.client = this.createOpenAPIClient({ baseUrl: e, headers: i }), this.uploadFileClient = this.createAxiosUploadClient({ baseUrl: e, headers: i });
112
+ }
113
+ }
114
+ var l, g;
115
+ class P {
116
+ constructor(t) {
117
+ s(this, "subscribers", /* @__PURE__ */ new Set());
118
+ S(this, l);
119
+ s(this, "initialState");
120
+ S(this, g);
121
+ s(this, "lifecycleListeners", /* @__PURE__ */ new Map());
122
+ s(this, "emitLifecycle", (t, e) => {
123
+ const i = this.lifecycleListeners.get(t);
124
+ if (i) {
125
+ const n = {
126
+ type: t,
127
+ timestamp: Date.now(),
128
+ data: e
129
+ };
130
+ i.forEach((r) => {
131
+ try {
132
+ r(n);
133
+ } catch {
134
+ }
135
+ });
136
+ }
137
+ });
138
+ s(this, "notifySubscribers", (t) => {
139
+ Array.from(this.subscribers).forEach((i) => {
140
+ try {
141
+ i(t);
142
+ } catch (n) {
143
+ this.emitLifecycle("error", { error: n });
144
+ }
145
+ });
146
+ });
147
+ /**
148
+ * Subscribe to state changes
149
+ * @param callback Function to call when state changes
150
+ * @returns Unsubscribe function
151
+ */
152
+ s(this, "subscribe", (t) => (this.subscribers.add(t), () => {
153
+ this.subscribers.delete(t);
154
+ }));
155
+ s(this, "onLifecycle", (t, e) => {
156
+ this.lifecycleListeners.has(t) || this.lifecycleListeners.set(t, /* @__PURE__ */ new Set());
157
+ const i = this.lifecycleListeners.get(t);
158
+ return i.add(e), () => {
159
+ i.delete(e), i.size === 0 && this.lifecycleListeners.delete(t);
160
+ };
161
+ });
162
+ /** Get the current state */
163
+ s(this, "get", () => c(this, l));
164
+ // TODO make this provide prev state
165
+ /**
166
+ * Set the state and notify subscribers if the state changes
167
+ * @param newState The new state to set
168
+ */
169
+ s(this, "set", (t) => {
170
+ this.emitLifecycle("beforeUpdate", {
171
+ previousState: c(this, l),
172
+ nextState: t
173
+ }), F(c(this, l), t) || (p(this, l, t), p(this, g, Date.now()), this.emitLifecycle("stateChange", { state: t }), this.notifySubscribers(t)), this.emitLifecycle("afterUpdate", { state: t });
174
+ });
175
+ // TODO make this provide prev state
176
+ s(this, "setPartial", (t) => {
177
+ if (t == null) return;
178
+ const e = { ...c(this, l), ...t };
179
+ this.set(e);
180
+ });
181
+ /**
182
+ * Clear all subscriptions
183
+ */
184
+ s(this, "clear", () => {
185
+ this.emitLifecycle(
186
+ "destroy"
187
+ /* DESTROY */
188
+ ), this.subscribers = /* @__PURE__ */ new Set(), this.lifecycleListeners = /* @__PURE__ */ new Map();
189
+ });
190
+ s(this, "reset", () => {
191
+ this.set(this.initialState);
192
+ });
193
+ s(this, "lastUpdated", () => c(this, g));
194
+ p(this, l, t), this.initialState = t, p(this, g, Date.now()), this.emitLifecycle("init", { initialState: c(this, l) });
195
+ }
196
+ }
197
+ l = new WeakMap(), g = new WeakMap();
198
+ class q {
199
+ constructor({ config: t, api: e }) {
200
+ s(this, "config");
201
+ s(this, "api");
202
+ s(this, "state");
203
+ s(this, "shouldCollectData", () => {
204
+ var e;
205
+ return !!(!((e = this.state.get().contact) != null && e.token) && this.config.collectUserData);
206
+ });
207
+ s(this, "autoCreateUnverifiedUser", async () => {
208
+ var t, e;
209
+ await this.createUnverifiedContact({
210
+ name: ((t = this.config.user) == null ? void 0 : t.name) || "Anonymous",
211
+ email: (e = this.config.user) == null ? void 0 : e.email
212
+ });
213
+ });
214
+ s(this, "createUnverifiedContact", async (t) => {
215
+ try {
216
+ this.state.setPartial({
217
+ isCreatingUnverifiedContact: !0,
218
+ isErrorCreatingUnverifiedContact: !1
219
+ });
220
+ const { data: e } = await this.api.createUnverifiedContact(t);
221
+ e != null && e.token ? (this.state.setPartial({ contact: { token: e.token } }), this.api.setAuthToken(e.token)) : this.state.setPartial({ isErrorCreatingUnverifiedContact: !0 });
222
+ } finally {
223
+ this.state.setPartial({ isCreatingUnverifiedContact: !1 });
224
+ }
225
+ });
226
+ this.config = t, this.api = e, this.state = new P({
227
+ contact: t.contactToken ? { token: t.contactToken } : null,
228
+ isCreatingUnverifiedContact: !1,
229
+ isErrorCreatingUnverifiedContact: !1
230
+ }), !t.contactToken && !t.collectUserData && this.autoCreateUnverifiedUser();
231
+ }
232
+ }
233
+ function w() {
234
+ return L();
235
+ }
236
+ class M {
237
+ constructor() {
238
+ s(this, "state", new P({
239
+ isPolling: !1,
240
+ isError: !1
241
+ }));
242
+ s(this, "abortController", new AbortController());
243
+ s(this, "reset", () => {
244
+ var t;
245
+ this.abortController.abort("Resetting poller"), (t = this.stopPolling) == null || t.call(this), this.stopPolling = null;
246
+ });
247
+ s(this, "stopPolling", null);
248
+ s(this, "startPolling", (t, e) => {
249
+ if (this.stopPolling) return;
250
+ const i = [], n = async () => {
251
+ this.abortController = new AbortController(), this.state.setPartial({ isPolling: !0 });
252
+ try {
253
+ await t(this.abortController.signal);
254
+ } catch (r) {
255
+ if (this.abortController.signal.aborted)
256
+ return;
257
+ console.error("Failed to poll:", r), this.state.setPartial({ isError: !0 });
258
+ } finally {
259
+ this.state.setPartial({ isPolling: !1 });
260
+ }
261
+ this.abortController.signal.aborted ? console.log("Poller aborted, not scheduling anymore") : i.push(setTimeout(n, e));
262
+ };
263
+ n(), this.stopPolling = () => {
264
+ i.forEach(clearTimeout), this.state.reset();
265
+ };
266
+ });
267
+ }
268
+ }
269
+ class d {
270
+ constructor({
271
+ config: t,
272
+ api: e,
273
+ sessionCtx: i
274
+ }) {
275
+ s(this, "config");
276
+ s(this, "api");
277
+ s(this, "sessionCtx");
278
+ s(this, "poller", new M());
279
+ s(this, "state", new P({
280
+ messages: [],
281
+ isSendingMessage: !1,
282
+ suggestedReplies: null
283
+ }));
284
+ s(this, "sendMessageAbortController", new AbortController());
285
+ s(this, "reset", () => {
286
+ this.sendMessageAbortController.abort("Resetting chat"), this.state.reset(), this.poller.reset();
287
+ });
288
+ s(this, "registerPolling", () => {
289
+ this.sessionCtx.state.subscribe(({ session: t }) => {
290
+ t != null && t.id ? this.poller.startPolling(async (e) => {
291
+ await this.fetchAndSetHistory(t.id, e);
292
+ }, 1e3) : this.poller.reset();
293
+ });
294
+ });
295
+ s(this, "sendMessage", async (t) => {
296
+ var n, r, u, f, m, C;
297
+ this.sendMessageAbortController = new AbortController();
298
+ const e = this.state.get().isSendingMessage, i = ((n = this.sessionCtx.state.get().session) == null ? void 0 : n.assignee.kind) === "ai";
299
+ if (e && i) {
300
+ console.warn("Cannot send messages while awaiting AI response");
301
+ return;
302
+ }
303
+ this.state.setPartial({ suggestedReplies: null });
304
+ try {
305
+ this.state.setPartial({ isSendingMessage: !0 });
306
+ const b = d.toUserMessage(
307
+ t.content,
308
+ t.attachments || void 0
309
+ ), k = this.state.get().messages;
310
+ if (this.state.setPartial({
311
+ messages: [...k, b]
312
+ }), !((r = this.sessionCtx.state.get().session) != null && r.id) && !await this.sessionCtx.createSession()) {
313
+ console.error("Failed to create session");
314
+ return;
315
+ }
316
+ const v = (u = this.sessionCtx.state.get().session) == null ? void 0 : u.id;
317
+ if (!v) return;
318
+ const { data: o } = await this.api.sendMessage(
319
+ {
320
+ uuid: b.id,
321
+ bot_token: this.config.token,
322
+ headers: this.config.headers,
323
+ query_params: this.config.queryParams,
324
+ session_id: v,
325
+ user: this.config.user,
326
+ ...t
327
+ },
328
+ this.sendMessageAbortController.signal
329
+ );
330
+ if (o != null && o.success) {
331
+ const h = d.toBotMessage(o);
332
+ if (h) {
333
+ const y = this.state.get().messages;
334
+ if (!!y.some(
335
+ (T) => T.id === h.id
336
+ )) return;
337
+ this.state.setPartial({ messages: [...y, h] });
338
+ } else
339
+ (f = o.options) != null && f.value && ((m = o.options) == null ? void 0 : m.value.length) > 0 && this.state.setPartial({ suggestedReplies: o.options.value });
340
+ } else {
341
+ const h = d.toErrorMessage(
342
+ ((C = o == null ? void 0 : o.error) == null ? void 0 : C.message) || "Unknown error occurred"
343
+ ), y = this.state.get().messages;
344
+ this.state.setPartial({
345
+ messages: [...y, h]
346
+ });
347
+ }
348
+ } catch (b) {
349
+ this.sendMessageAbortController.signal.aborted || console.error("Failed to send message:", b);
350
+ } finally {
351
+ this.state.setPartial({ isSendingMessage: !1 });
352
+ }
353
+ });
354
+ s(this, "fetchAndSetHistory", async (t, e) => {
355
+ var r;
356
+ const i = (r = this.state.get().messages.at(-1)) == null ? void 0 : r.timestamp, { data: n } = await this.api.getSessionHistory({
357
+ sessionId: t,
358
+ lastMessageTimestamp: i,
359
+ abortSignal: e
360
+ });
361
+ if (n && n.length > 0) {
362
+ const u = this.state.get().messages, f = n.map(d.mapHistoryToMessage).filter(
363
+ (m) => !u.some((C) => C.id === m.id)
364
+ );
365
+ this.state.setPartial({
366
+ messages: [...u, ...f]
367
+ });
368
+ }
369
+ });
370
+ this.config = t, this.api = e, this.sessionCtx = i, this.registerPolling();
371
+ }
372
+ /** Not the best name but whatever */
373
+ static mapHistoryToMessage(t) {
374
+ const e = {
375
+ id: t.publicId,
376
+ timestamp: t.sentAt || "",
377
+ attachments: t.attachments || void 0
378
+ };
379
+ return t.sender.kind === "user" ? {
380
+ ...e,
381
+ type: "FROM_USER",
382
+ content: t.content.text || "",
383
+ deliveredAt: t.sentAt || ""
384
+ } : t.sender.kind === "agent" ? {
385
+ ...e,
386
+ type: "FROM_AGENT",
387
+ component: "agent_message",
388
+ data: {
389
+ message: t.content.text || ""
390
+ }
391
+ } : {
392
+ ...e,
393
+ type: "FROM_BOT",
394
+ component: "bot_message",
395
+ agent: {
396
+ id: null,
397
+ name: t.sender.name || "",
398
+ isAi: t.sender.kind === "ai",
399
+ avatar: t.sender.avatar || null
400
+ },
401
+ data: {
402
+ message: t.content.text
403
+ }
404
+ };
405
+ }
406
+ static toUserMessage(t, e) {
407
+ return {
408
+ id: w(),
409
+ type: "FROM_USER",
410
+ content: t,
411
+ deliveredAt: (/* @__PURE__ */ new Date()).toISOString(),
412
+ attachments: e,
413
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
414
+ };
415
+ }
416
+ static toBotMessage(t) {
417
+ if (t.success && t.autopilotResponse)
418
+ return {
419
+ type: "FROM_BOT",
420
+ id: t.autopilotResponse.id || w(),
421
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
422
+ component: "bot_message",
423
+ data: {
424
+ message: t.autopilotResponse.value.content
425
+ }
426
+ };
427
+ if (t.success && t.uiResponse) {
428
+ const e = t.uiResponse.value;
429
+ return {
430
+ type: "FROM_BOT",
431
+ id: w(),
432
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
433
+ component: e.name,
434
+ data: e.request_response
435
+ };
436
+ }
437
+ return null;
438
+ }
439
+ static toErrorMessage(t) {
440
+ return {
441
+ type: "FROM_BOT",
442
+ id: w(),
443
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
444
+ component: "TEXT",
445
+ data: {
446
+ message: t,
447
+ variant: "error"
448
+ }
449
+ };
450
+ }
451
+ }
452
+ class _ {
453
+ constructor(t) {
454
+ s(this, "api");
455
+ s(this, "poller", new M());
456
+ s(this, "state", new P({
457
+ session: null,
458
+ isCreatingSession: !1
459
+ }));
460
+ /** Clears the session and stops polling */
461
+ s(this, "reset", async () => {
462
+ this.state.reset(), this.poller.reset();
463
+ });
464
+ s(this, "registerPolling", () => {
465
+ this.state.subscribe(({ session: t }) => {
466
+ t != null && t.id ? this.poller.startPolling(async (e) => {
467
+ const { data: i } = await this.fetch(t.id, e);
468
+ i && this.state.setPartial({ session: i });
469
+ }, 1e3) : this.poller.reset();
470
+ });
471
+ });
472
+ /**
473
+ * Creates a new session
474
+ * @returns The session
475
+ */
476
+ s(this, "createSession", async () => {
477
+ this.state.setPartial({ session: null, isCreatingSession: !0 });
478
+ const { data: t, error: e } = await this.api.createSession();
479
+ return t ? (this.state.setPartial({ session: t, isCreatingSession: !1 }), t) : (console.error("Failed to create session:", e), null);
480
+ });
481
+ /**
482
+ * Fetches the session from the API
483
+ * @param id - The ID of the session to fetch
484
+ * @returns The session
485
+ */
486
+ s(this, "fetch", async (t, e) => this.api.getSession({ sessionId: t, abortSignal: e }));
487
+ this.api = t, this.registerPolling();
488
+ }
489
+ }
490
+ class W {
491
+ constructor({ config: t }) {
492
+ s(this, "config");
493
+ s(this, "api");
494
+ s(this, "contactCtx");
495
+ s(this, "sessionCtx");
496
+ s(this, "messageCtx");
497
+ s(this, "resetChat", () => {
498
+ this.sessionCtx.reset(), this.messageCtx.reset();
499
+ });
500
+ this.config = t, this.api = new B({ config: t }), this.contactCtx = new q({
501
+ api: this.api,
502
+ config: this.config
503
+ }), this.sessionCtx = new _(this.api), this.messageCtx = new d({
504
+ config: this.config,
505
+ api: this.api,
506
+ sessionCtx: this.sessionCtx
507
+ });
508
+ }
509
+ }
510
+ export {
511
+ P,
512
+ W
513
+ };
514
+ //# sourceMappingURL=widget-DbgWez1r.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-DbgWez1r.js","sources":["../src/headless/core/sdk/index.ts","../src/headless/core/api.ts","../src/headless/core/utils/PubSub.ts","../src/headless/core/context/contact.ts","../src/headless/core/utils/uuid.ts","../src/headless/core/utils/Poller.ts","../src/headless/core/context/message.ts","../src/headless/core/context/session.ts","../src/headless/core/context/widget.ts"],"sourcesContent":["import createClient, { type Middleware } from \"openapi-fetch\";\nimport type { paths } from \"./schema\";\nimport type { components } from \"./schema\";\n\ntype Options = {\n baseUrl: string;\n onRequest?: Middleware[\"onRequest\"];\n onResponse?: Middleware[\"onResponse\"];\n onError?: Middleware[\"onError\"];\n};\n\nconst defaultOnError: Middleware[\"onError\"] = (onErrorOptions) => {\n console.log(onErrorOptions.error);\n};\n\nexport const basicClient = (options: Options) => {\n const client = createClient<paths>({\n baseUrl: options.baseUrl,\n });\n\n const middlewares: Middleware = {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n onError: options.onError || defaultOnError,\n };\n\n client.use(middlewares);\n return client;\n};\n\nexport type Endpoint = keyof paths;\nexport type Dto = components[\"schemas\"];\n","import axios, { AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport { Dto, Endpoint, basicClient } from \"./sdk\";\nimport { WidgetConfig } from \"./types/WidgetConfig\";\nimport { SendMessageDto, VoteInputDto } from \"./types/schemas\";\n\nexport class ApiCaller {\n private client: ReturnType<typeof basicClient>;\n private uploadFileClient: AxiosInstance;\n private config: WidgetConfig;\n\n constructor({\n config,\n }: {\n config: WidgetConfig;\n }) {\n this.config = config;\n const { baseUrl, headers } = this.constructClientOptions(\n config.contactToken,\n );\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n this.uploadFileClient = this.createAxiosUploadClient({ baseUrl, headers });\n }\n\n private constructClientOptions = (token: string | null | undefined) => {\n const baseUrl = this.config.apiUrl || \"https://api.open.cx\";\n const headers = {\n \"X-Bot-Token\": this.config.token,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: token ? `Bearer ${token}` : undefined,\n };\n\n return { baseUrl, headers };\n };\n\n private createOpenAPIClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n return basicClient({\n baseUrl,\n onRequest: ({ request }) => {\n Object.entries(headers).forEach(([key, value]) => {\n if (value) {\n request.headers.set(key, value);\n }\n });\n },\n });\n };\n private createAxiosUploadClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n const uploadPath = \"/backend/widget/v2/upload\" satisfies Endpoint;\n return axios.create({\n baseURL: `${baseUrl}${uploadPath}`,\n headers,\n });\n };\n\n setAuthToken = (token: string) => {\n const { baseUrl, headers } = this.constructClientOptions(token);\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n this.uploadFileClient = this.createAxiosUploadClient({ baseUrl, headers });\n };\n\n widgetPrelude = async () => {\n return await this.client.GET(\"/backend/widget/v2/prelude\", {\n params: { header: { \"X-Bot-Token\": this.config.token } },\n });\n };\n\n sendMessage = async (body: SendMessageDto, abortSignal?: AbortSignal) => {\n return await this.client.POST(\"/backend/widget/v2/chat/send\", {\n body,\n signal: abortSignal,\n });\n };\n\n getSessionHistory = async ({\n sessionId,\n lastMessageTimestamp,\n abortSignal,\n }: {\n sessionId: string;\n lastMessageTimestamp?: string;\n abortSignal: AbortSignal;\n }) => {\n const query = lastMessageTimestamp ? { lastMessageTimestamp } : undefined;\n return await this.client.GET(\n \"/backend/widget/v2/session/history/{sessionId}\",\n { params: { path: { sessionId }, query }, signal: abortSignal },\n );\n };\n\n createUnverifiedContact = async (body: Dto[\"CreateUnverifiedContactDto\"]) => {\n return await this.client.POST(\n \"/backend/widget/v2/contact/create-unverified\",\n {\n params: { header: { \"x-bot-token\": this.config.token } },\n body,\n },\n );\n };\n\n createSession = async () => {\n return await this.client.POST(\"/backend/widget/v2/create-session\");\n };\n\n getSession = async ({\n sessionId,\n abortSignal,\n }: { sessionId: string; abortSignal: AbortSignal }) => {\n return await this.client.GET(\"/backend/widget/v2/session/{sessionId}\", {\n params: { path: { sessionId } },\n signal: abortSignal,\n });\n };\n\n uploadFile = async (\n file: {\n id: string;\n file: File;\n },\n config: Partial<AxiosRequestConfig> = {},\n ) => {\n const formData = new FormData();\n formData.append(\"file\", file.file);\n\n // Couldn't get this to work with the openapi client... dunno why...\n const { data } = await this.uploadFileClient.post<\n Dto[\"UploadWidgetFileResponseDto\"]\n >(\"\", formData, {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n ...config,\n });\n return data;\n };\n\n vote = async (body: VoteInputDto) => {\n return await this.client.POST(\"/backend/widget/v2/chat/vote\", { body });\n };\n}\n","import isEqual from \"lodash.isequal\";\n\nexport type Subscriber<T> = (data: T) => void;\n\nexport enum LifecycleEvent {\n INIT = \"init\",\n STATE_CHANGE = \"stateChange\",\n BEFORE_UPDATE = \"beforeUpdate\",\n AFTER_UPDATE = \"afterUpdate\",\n DESTROY = \"destroy\",\n ERROR = \"error\",\n}\n\ntype LifecycleListener = (event: {\n type: LifecycleEvent;\n timestamp: number;\n data?: any;\n}) => void;\n\nexport class PubSub<S> {\n private subscribers = new Set<Subscriber<S>>();\n #state: S;\n private initialState: S;\n #lastUpdated: number | null;\n private lifecycleListeners: Map<LifecycleEvent, Set<LifecycleListener>> =\n new Map();\n\n constructor(state: S) {\n this.#state = state;\n this.initialState = state;\n this.#lastUpdated = Date.now();\n this.emitLifecycle(LifecycleEvent.INIT, { initialState: this.#state });\n }\n\n private emitLifecycle = (event: LifecycleEvent, data?: any) => {\n const listeners = this.lifecycleListeners.get(event);\n if (listeners) {\n const eventData = {\n type: event,\n timestamp: Date.now(),\n data,\n };\n listeners.forEach((listener) => {\n try {\n listener(eventData);\n } catch {\n // ignore error\n }\n });\n }\n };\n\n private notifySubscribers = (state: S) => {\n const subscribersArray = Array.from(this.subscribers);\n subscribersArray.forEach((callback) => {\n try {\n callback(state);\n } catch (error) {\n this.emitLifecycle(LifecycleEvent.ERROR, { error });\n }\n });\n };\n\n /**\n * Subscribe to state changes\n * @param callback Function to call when state changes\n * @returns Unsubscribe function\n */\n subscribe = (callback: Subscriber<S>): (() => void) => {\n this.subscribers.add(callback);\n // Don't call the callback immediately with current state\n return () => {\n this.subscribers.delete(callback);\n };\n };\n\n onLifecycle = (\n event: LifecycleEvent,\n listener: LifecycleListener,\n ): (() => void) => {\n if (!this.lifecycleListeners.has(event)) {\n this.lifecycleListeners.set(event, new Set());\n }\n const listeners = this.lifecycleListeners.get(event)!;\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) {\n this.lifecycleListeners.delete(event);\n }\n };\n };\n\n /** Get the current state */\n get = (): S => {\n return this.#state;\n };\n\n // TODO make this provide prev state\n /**\n * Set the state and notify subscribers if the state changes\n * @param newState The new state to set\n */\n set = (newState: S): void => {\n this.emitLifecycle(LifecycleEvent.BEFORE_UPDATE, {\n previousState: this.#state,\n nextState: newState,\n });\n\n if (!isEqual(this.#state, newState)) {\n this.#state = newState;\n this.#lastUpdated = Date.now();\n this.emitLifecycle(LifecycleEvent.STATE_CHANGE, { state: newState });\n this.notifySubscribers(newState);\n }\n\n this.emitLifecycle(LifecycleEvent.AFTER_UPDATE, { state: newState });\n };\n\n // TODO make this provide prev state\n setPartial = (_s: Partial<S>): void => {\n if (_s === undefined || _s === null) return;\n const newState = { ...this.#state, ..._s };\n this.set(newState);\n };\n\n /**\n * Clear all subscriptions\n */\n clear = (): void => {\n this.emitLifecycle(LifecycleEvent.DESTROY);\n this.subscribers = new Set(); // Create a new Set instead of just clearing\n this.lifecycleListeners = new Map();\n };\n\n reset = (): void => {\n this.set(this.initialState);\n };\n\n lastUpdated = (): number | null => {\n return this.#lastUpdated;\n };\n}\n","import { PubSub } from \"../utils/PubSub\";\nimport { ApiCaller } from \"../api\";\nimport { Dto } from \"src/headless/core/sdk\";\nimport { WidgetConfig } from \"src/headless/core/types/WidgetConfig\";\n\ntype ContactState = {\n contact: { token: string } | null;\n isCreatingUnverifiedContact: boolean;\n isErrorCreatingUnverifiedContact: boolean;\n};\n\nexport type CreateContactHandlerOptions = {\n api: ApiCaller;\n config: WidgetConfig;\n};\n\nexport class ContactCtx {\n private config: WidgetConfig;\n private api: ApiCaller;\n state: PubSub<ContactState>;\n\n constructor({ config, api }: CreateContactHandlerOptions) {\n this.config = config;\n this.api = api;\n\n this.state = new PubSub<ContactState>({\n contact: config.contactToken ? { token: config.contactToken } : null,\n isCreatingUnverifiedContact: false,\n isErrorCreatingUnverifiedContact: false,\n });\n\n if (!config.contactToken && !config.collectUserData) {\n this.autoCreateUnverifiedUser();\n }\n }\n\n shouldCollectData = (): boolean => {\n const currentState = this.state.get();\n\n if (!currentState.contact?.token && this.config.collectUserData) {\n return true;\n } else {\n return false;\n }\n };\n\n autoCreateUnverifiedUser = async () => {\n await this.createUnverifiedContact({\n name: this.config.user?.name || \"Anonymous\",\n email: this.config.user?.email,\n });\n };\n\n createUnverifiedContact = async (\n payload: Dto[\"CreateUnverifiedContactDto\"],\n ): Promise<void> => {\n try {\n this.state.setPartial({\n isCreatingUnverifiedContact: true,\n isErrorCreatingUnverifiedContact: false,\n });\n\n const { data } = await this.api.createUnverifiedContact(payload);\n if (data?.token) {\n this.state.setPartial({ contact: { token: data.token } });\n this.api.setAuthToken(data.token);\n } else {\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n }\n } finally {\n this.state.setPartial({ isCreatingUnverifiedContact: false });\n }\n };\n}\n","import { v4 as uuidv4 } from \"uuid\";\n\nexport function genUuid() {\n return uuidv4();\n}\n","import { PubSub } from \"src/headless/core/utils/PubSub\";\n\nexport type PollingState = {\n isPolling: boolean;\n isError: boolean;\n};\n\nexport class Poller {\n state = new PubSub<PollingState>({\n isPolling: false,\n isError: false,\n });\n private abortController = new AbortController();\n\n reset = () => {\n this.abortController.abort(\"Resetting poller\");\n this.stopPolling?.();\n this.stopPolling = null;\n };\n\n stopPolling: (() => void) | null = null;\n\n startPolling = (\n cb: (abortSignal: AbortSignal) => Promise<void>,\n interval: number,\n ) => {\n if (this.stopPolling) return;\n\n const timeouts: NodeJS.Timeout[] = [];\n\n const poll = async () => {\n this.abortController = new AbortController();\n this.state.setPartial({ isPolling: true });\n\n try {\n await cb(this.abortController.signal);\n } catch (error) {\n if (this.abortController.signal.aborted) {\n // If aborted, just return and do not schedule the nest poll\n return;\n } else {\n console.error(\"Failed to poll:\", error);\n this.state.setPartial({ isError: true });\n } \n } finally {\n this.state.setPartial({ isPolling: false });\n }\n\n // Another check to stop scheduling polls in case someone removes the early return in the catch above\n if (this.abortController.signal.aborted) {\n console.log(\"Poller aborted, not scheduling anymore\");\n } else {\n timeouts.push(setTimeout(poll, interval));\n }\n };\n\n poll();\n\n this.stopPolling = () => {\n timeouts.forEach(clearTimeout);\n this.state.reset();\n };\n };\n}\n","import {\n MessageAttachmentType,\n SendMessageOutputDto,\n MessageDto,\n SomeOptional,\n SafeOmit,\n SendMessageDto,\n WidgetConfig,\n} from \"src/headless/core\";\nimport {\n BotMessageType,\n MessageType,\n UserMessageType,\n} from \"src/headless/core/types/messages\";\nimport { genUuid } from \"../utils/uuid\";\nimport { ApiCaller } from \"../api\";\nimport { SessionCtx } from \"./session\";\nimport { Poller } from \"src/headless/core/utils/Poller\";\nimport { PubSub } from \"src/headless/core/utils/PubSub\";\n\nexport class MessageCtx {\n private config: WidgetConfig;\n private api: ApiCaller;\n private sessionCtx: SessionCtx;\n private poller = new Poller();\n\n public state = new PubSub<{\n messages: MessageType[];\n isSendingMessage: boolean;\n suggestedReplies: string[] | null;\n }>({\n messages: [],\n isSendingMessage: false,\n suggestedReplies: null,\n });\n\n private sendMessageAbortController = new AbortController();\n\n constructor({\n config,\n api,\n sessionCtx,\n }: { config: WidgetConfig; api: ApiCaller; sessionCtx: SessionCtx }) {\n this.config = config;\n this.api = api;\n this.sessionCtx = sessionCtx;\n\n this.registerPolling();\n }\n\n reset = () => {\n this.sendMessageAbortController.abort(\"Resetting chat\");\n this.state.reset();\n // The poller should automatically reset, since we're subscribed to the session state, and whenever it's null, the poller resets... but just in case, let's reset it here as well\n this.poller.reset();\n };\n\n registerPolling = () => {\n this.sessionCtx.state.subscribe(({ session }) => {\n if (session?.id) {\n this.poller.startPolling(async (abortSignal) => {\n await this.fetchAndSetHistory(session.id, abortSignal);\n }, 1000);\n } else {\n this.poller.reset();\n }\n });\n };\n\n sendMessage = async (\n input: SomeOptional<\n SafeOmit<SendMessageDto, \"bot_token\" | \"uuid\">,\n \"session_id\" | \"user\"\n >,\n ): Promise<void> => {\n this.sendMessageAbortController = new AbortController();\n /* ------------------------------------------------------ */\n /* Prevent sending while waiting for AI res */\n /* ------------------------------------------------------ */\n const isSending = this.state.get().isSendingMessage;\n const isAssignedToAI =\n this.sessionCtx.state.get().session?.assignee.kind === \"ai\";\n if (isSending && isAssignedToAI) {\n console.warn(\"Cannot send messages while awaiting AI response\");\n return;\n }\n\n /* ------------------------------------------------------ */\n /* Clear suggested replies */\n /* ------------------------------------------------------ */\n this.state.setPartial({ suggestedReplies: null });\n\n try {\n this.state.setPartial({ isSendingMessage: true });\n /* ------------------------------------------------------ */\n /* Optimistically add message to rendered messages */\n /* ------------------------------------------------------ */\n const userMessage = MessageCtx.toUserMessage(\n input.content,\n input.attachments || undefined,\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, userMessage],\n });\n\n /* ------------------------------------------------------ */\n /* Create session if not exists */\n /* ------------------------------------------------------ */\n if (!this.sessionCtx.state.get().session?.id) {\n const createdSession = await this.sessionCtx.createSession();\n\n // TODO: apply some retry logic here\n if (!createdSession) {\n console.error(\"Failed to create session\");\n return;\n }\n }\n const sessionId = this.sessionCtx.state.get().session?.id;\n if (!sessionId) return;\n\n /* ------------------------------------------------------ */\n /* Send and wait for bot response */\n /* ------------------------------------------------------ */\n const { data } = await this.api.sendMessage(\n {\n uuid: userMessage.id,\n bot_token: this.config.token,\n headers: this.config.headers,\n query_params: this.config.queryParams,\n session_id: sessionId,\n user: this.config.user,\n ...input,\n },\n this.sendMessageAbortController.signal,\n );\n\n if (data?.success) {\n /* ------------------------------------------------------ */\n /* Append bot reply if not fetched from polling */\n /* ------------------------------------------------------ */\n const botMessage = MessageCtx.toBotMessage(data);\n if (botMessage) {\n const prevMessages = this.state.get().messages;\n const shouldAppend = !prevMessages.some(\n (m) => m.id === botMessage.id,\n );\n if (!shouldAppend) return;\n this.state.setPartial({ messages: [...prevMessages, botMessage] });\n } else {\n /* ------------------------------------------------------ */\n /* Check if bot responded with suggested replies */\n /* ------------------------------------------------------ */\n if (data.options?.value && data.options?.value.length > 0) {\n this.state.setPartial({ suggestedReplies: data.options.value });\n }\n }\n } else {\n const errorMessage = MessageCtx.toErrorMessage(\n data?.error?.message || \"Unknown error occurred\",\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, errorMessage],\n });\n }\n } catch (error) {\n if (!this.sendMessageAbortController.signal.aborted) {\n console.error(\"Failed to send message:\", error);\n }\n } finally {\n this.state.setPartial({ isSendingMessage: false });\n }\n };\n\n fetchAndSetHistory = async (\n sessionId: string,\n abortSignal: AbortSignal,\n ): Promise<void> => {\n const lastMessageTimestamp = this.state.get().messages.at(-1)?.timestamp;\n\n const { data: response } = await this.api.getSessionHistory({\n sessionId,\n lastMessageTimestamp,\n abortSignal,\n });\n\n if (response && response.length > 0) {\n // Get a fresh reference to current messages after the poll is done\n const prevMessages = this.state.get().messages;\n const newMessages = response\n .map(MessageCtx.mapHistoryToMessage)\n .filter(\n (newMsg) =>\n !prevMessages.some((existingMsg) => existingMsg.id === newMsg.id),\n );\n this.state.setPartial({\n messages: [...prevMessages, ...newMessages],\n });\n\n // if (newMessages.length > 0) {\n // // const playSoundEffects = config?.settings?.playSoundEffects;\n // // Play notification sound for new messages if enabled\n // // if (\n // // playSoundEffects &&\n // // platform?.audio &&\n // // isAudioAvailable(platform.audio)\n // // ) {\n // // const botMessages = newMessages.filter(\n // // (msg) => msg.type === \"FROM_BOT\",\n // // );\n // // if (botMessages.length > 0) {\n // // await safeAudioOperation(\n // // () => platform.audio!.playNotification(),\n // // \"Failed to play notification sound for new messages\",\n // // );\n // // }\n // // }\n\n // }\n }\n };\n\n /** Not the best name but whatever */\n static mapHistoryToMessage(history: MessageDto): MessageType {\n const commonFields = {\n id: history.publicId,\n timestamp: history.sentAt || \"\",\n attachments: history.attachments || undefined,\n };\n\n if (history.sender.kind === \"user\") {\n return {\n ...commonFields,\n type: \"FROM_USER\",\n content: history.content.text || \"\",\n deliveredAt: history.sentAt || \"\",\n };\n }\n\n if (history.sender.kind === \"agent\") {\n return {\n ...commonFields,\n type: \"FROM_AGENT\",\n component: \"agent_message\",\n data: {\n message: history.content.text || \"\",\n },\n };\n }\n\n return {\n ...commonFields,\n type: \"FROM_BOT\",\n component: \"bot_message\",\n agent: {\n id: null,\n name: history.sender.name || \"\",\n isAi: history.sender.kind === \"ai\",\n avatar: history.sender.avatar || null,\n },\n data: {\n message: history.content.text,\n },\n };\n }\n\n static toUserMessage(\n content: string,\n attachments?: MessageAttachmentType[],\n ): UserMessageType {\n return {\n id: genUuid(),\n type: \"FROM_USER\",\n content,\n deliveredAt: new Date().toISOString(),\n attachments,\n timestamp: new Date().toISOString(),\n };\n }\n\n static toBotMessage(response: SendMessageOutputDto): BotMessageType | null {\n if (response.success && response.autopilotResponse) {\n return {\n type: \"FROM_BOT\",\n id: response.autopilotResponse.id || genUuid(),\n timestamp: new Date().toISOString(),\n component: \"bot_message\",\n data: {\n message: response.autopilotResponse.value.content,\n },\n };\n }\n\n if (response.success && response.uiResponse) {\n const uiVal = response.uiResponse.value;\n return {\n type: \"FROM_BOT\" as const,\n id: genUuid(),\n timestamp: new Date().toISOString(),\n component: uiVal.name,\n data: uiVal.request_response,\n };\n }\n\n return null;\n }\n\n static toErrorMessage(message: string) {\n return {\n type: \"FROM_BOT\" as const,\n id: genUuid(),\n timestamp: new Date().toISOString(),\n component: \"TEXT\",\n data: {\n message,\n variant: \"error\",\n },\n };\n }\n}\n","import { ApiCaller } from \"src/headless/core/api\";\nimport { SessionDto } from \"src/headless/core\";\nimport { Poller } from \"src/headless/core/utils/Poller\";\nimport { PubSub } from \"src/headless/core/utils/PubSub\";\n\nexport class SessionCtx {\n private api: ApiCaller;\n private poller = new Poller();\n\n public state = new PubSub<{\n session: SessionDto | null;\n isCreatingSession: boolean;\n }>({\n session: null,\n isCreatingSession: false,\n });\n\n constructor(api: ApiCaller) {\n this.api = api;\n this.registerPolling();\n }\n\n /** Clears the session and stops polling */\n reset = async () => {\n this.state.reset();\n // The poller should automatically reset, since we're subscribed to the session state, and whenever it's null, the poller resets... but just in case, let's reset it here as well\n this.poller.reset();\n };\n\n registerPolling = () => {\n this.state.subscribe(({ session }) => {\n if (session?.id) {\n this.poller.startPolling(async (abortSignal) => {\n const { data } = await this.fetch(session.id, abortSignal);\n data && this.state.setPartial({ session: data });\n }, 1000);\n } else {\n this.poller.reset();\n }\n });\n };\n\n /**\n * Creates a new session\n * @returns The session\n */\n createSession = async () => {\n this.state.setPartial({ session: null, isCreatingSession: true });\n\n const { data: session, error } = await this.api.createSession();\n if (session) {\n this.state.setPartial({ session, isCreatingSession: false });\n return session;\n }\n\n console.error(\"Failed to create session:\", error);\n return null;\n };\n\n /**\n * Fetches the session from the API\n * @param id - The ID of the session to fetch\n * @returns The session\n */\n fetch = async (sessionId: string, abortSignal: AbortSignal) => {\n return this.api.getSession({ sessionId, abortSignal });\n };\n}\n","import { WidgetConfig } from \"src/headless/core/types/WidgetConfig\";\nimport { ApiCaller } from \"../api\";\nimport { ContactCtx } from \"./contact\";\nimport { MessageCtx } from \"./message\";\nimport { SessionCtx } from \"./session\";\n\nexport class WidgetCtx {\n public config: WidgetConfig;\n public api: ApiCaller;\n public contactCtx: ContactCtx;\n public sessionCtx: SessionCtx;\n public messageCtx: MessageCtx;\n\n constructor({ config }: { config: WidgetConfig }) {\n this.config = config;\n this.api = new ApiCaller({ config });\n\n this.contactCtx = new ContactCtx({\n api: this.api,\n config: this.config,\n });\n\n this.sessionCtx = new SessionCtx(this.api);\n this.messageCtx = new MessageCtx({\n config: this.config,\n api: this.api,\n sessionCtx: this.sessionCtx,\n });\n }\n\n resetChat = () => {\n this.sessionCtx.reset();\n this.messageCtx.reset();\n };\n}\n"],"names":["defaultOnError","onErrorOptions","basicClient","options","client","createClient","middlewares","ApiCaller","config","__publicField","token","baseUrl","headers","request","key","value","axios","body","abortSignal","sessionId","lastMessageTimestamp","query","file","formData","data","PubSub","state","__privateAdd","_state","_lastUpdated","event","listeners","eventData","listener","callback","error","__privateGet","newState","isEqual","__privateSet","_s","ContactCtx","api","_a","_b","payload","genUuid","uuidv4","Poller","cb","interval","timeouts","poll","MessageCtx","sessionCtx","session","input","isSending","isAssignedToAI","userMessage","currentMessages","_c","botMessage","prevMessages","m","_d","_e","errorMessage","_f","response","newMessages","newMsg","existingMsg","history","commonFields","content","attachments","uiVal","message","SessionCtx","WidgetCtx"],"mappings":"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"}