@blockspark/chat-widget 1.0.7 → 1.0.9

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 (202) hide show
  1. package/README.md +117 -140
  2. package/dist/_virtual/_plugin-vue_export-helper.cjs.js +2 -0
  3. package/dist/_virtual/_plugin-vue_export-helper.cjs.js.map +1 -0
  4. package/dist/_virtual/_plugin-vue_export-helper.esm.js +11 -0
  5. package/dist/_virtual/_plugin-vue_export-helper.esm.js.map +1 -0
  6. package/dist/components/ChatWidget.cjs.js +2 -0
  7. package/dist/components/ChatWidget.cjs.js.map +1 -0
  8. package/dist/components/ChatWidget.d.ts.map +1 -1
  9. package/dist/components/ChatWidget.esm.js +1129 -0
  10. package/dist/components/ChatWidget.esm.js.map +1 -0
  11. package/dist/components/ChatWidget.vue.cjs.js +2 -0
  12. package/dist/components/ChatWidget.vue.cjs.js.map +1 -0
  13. package/dist/components/ChatWidget.vue.cjs2.js +2 -0
  14. package/dist/components/ChatWidget.vue.cjs2.js.map +1 -0
  15. package/dist/components/ChatWidget.vue.esm.js +8 -0
  16. package/dist/components/ChatWidget.vue.esm.js.map +1 -0
  17. package/dist/components/ChatWidget.vue.esm2.js +374 -0
  18. package/dist/components/ChatWidget.vue.esm2.js.map +1 -0
  19. package/dist/composables/useChatWidget.cjs.js +2 -0
  20. package/dist/composables/useChatWidget.cjs.js.map +1 -0
  21. package/dist/composables/useChatWidget.d.ts +35 -0
  22. package/dist/composables/useChatWidget.d.ts.map +1 -0
  23. package/dist/composables/useChatWidget.esm.js +75 -0
  24. package/dist/composables/useChatWidget.esm.js.map +1 -0
  25. package/dist/core/stateManager.cjs.js +2 -0
  26. package/dist/core/stateManager.cjs.js.map +1 -0
  27. package/dist/core/stateManager.esm.js +915 -0
  28. package/dist/core/stateManager.esm.js.map +1 -0
  29. package/dist/entry/nuxt.d.ts +9 -4
  30. package/dist/entry/nuxt.d.ts.map +1 -1
  31. package/dist/entry/vanilla.cjs.js +2 -0
  32. package/dist/entry/vanilla.cjs.js.map +1 -0
  33. package/dist/entry/vanilla.esm.js +50 -0
  34. package/dist/entry/vanilla.esm.js.map +1 -0
  35. package/dist/entry/vue.d.ts +8 -5
  36. package/dist/entry/vue.d.ts.map +1 -1
  37. package/dist/hooks/useChatMode.cjs.js +2 -0
  38. package/dist/hooks/useChatMode.cjs.js.map +1 -0
  39. package/dist/hooks/useChatMode.esm.js +61 -0
  40. package/dist/hooks/useChatMode.esm.js.map +1 -0
  41. package/dist/index.cjs.js +2 -2
  42. package/dist/index.cjs.js.map +1 -0
  43. package/dist/index.esm.js +16 -2
  44. package/dist/index.esm.js.map +1 -0
  45. package/dist/node_modules/jose/dist/browser/jws/compact/sign.cjs.js +2 -0
  46. package/dist/node_modules/jose/dist/browser/jws/compact/sign.cjs.js.map +1 -0
  47. package/dist/node_modules/jose/dist/browser/jws/compact/sign.esm.js +21 -0
  48. package/dist/node_modules/jose/dist/browser/jws/compact/sign.esm.js.map +1 -0
  49. package/dist/node_modules/jose/dist/browser/jws/flattened/sign.cjs.js +2 -0
  50. package/dist/node_modules/jose/dist/browser/jws/flattened/sign.cjs.js.map +1 -0
  51. package/dist/node_modules/jose/dist/browser/jws/flattened/sign.esm.js +84 -0
  52. package/dist/node_modules/jose/dist/browser/jws/flattened/sign.esm.js.map +1 -0
  53. package/dist/node_modules/jose/dist/browser/jwt/produce.cjs.js +2 -0
  54. package/dist/node_modules/jose/dist/browser/jwt/produce.cjs.js.map +1 -0
  55. package/dist/node_modules/jose/dist/browser/jwt/produce.esm.js +72 -0
  56. package/dist/node_modules/jose/dist/browser/jwt/produce.esm.js.map +1 -0
  57. package/dist/node_modules/jose/dist/browser/jwt/sign.cjs.js +2 -0
  58. package/dist/node_modules/jose/dist/browser/jwt/sign.cjs.js.map +1 -0
  59. package/dist/node_modules/jose/dist/browser/jwt/sign.esm.js +22 -0
  60. package/dist/node_modules/jose/dist/browser/jwt/sign.esm.js.map +1 -0
  61. package/dist/node_modules/jose/dist/browser/key/import.cjs.js +2 -0
  62. package/dist/node_modules/jose/dist/browser/key/import.cjs.js.map +1 -0
  63. package/dist/node_modules/jose/dist/browser/key/import.esm.js +11 -0
  64. package/dist/node_modules/jose/dist/browser/key/import.esm.js.map +1 -0
  65. package/dist/node_modules/jose/dist/browser/lib/buffer_utils.cjs.js +2 -0
  66. package/dist/node_modules/jose/dist/browser/lib/buffer_utils.cjs.js.map +1 -0
  67. package/dist/node_modules/jose/dist/browser/lib/buffer_utils.esm.js +18 -0
  68. package/dist/node_modules/jose/dist/browser/lib/buffer_utils.esm.js.map +1 -0
  69. package/dist/node_modules/jose/dist/browser/lib/check_key_type.cjs.js +2 -0
  70. package/dist/node_modules/jose/dist/browser/lib/check_key_type.cjs.js.map +1 -0
  71. package/dist/node_modules/jose/dist/browser/lib/check_key_type.esm.js +77 -0
  72. package/dist/node_modules/jose/dist/browser/lib/check_key_type.esm.js.map +1 -0
  73. package/dist/node_modules/jose/dist/browser/lib/crypto_key.cjs.js +2 -0
  74. package/dist/node_modules/jose/dist/browser/lib/crypto_key.cjs.js.map +1 -0
  75. package/dist/node_modules/jose/dist/browser/lib/crypto_key.esm.js +101 -0
  76. package/dist/node_modules/jose/dist/browser/lib/crypto_key.esm.js.map +1 -0
  77. package/dist/node_modules/jose/dist/browser/lib/epoch.cjs.js +2 -0
  78. package/dist/node_modules/jose/dist/browser/lib/epoch.cjs.js.map +1 -0
  79. package/dist/node_modules/jose/dist/browser/lib/epoch.esm.js +5 -0
  80. package/dist/node_modules/jose/dist/browser/lib/epoch.esm.js.map +1 -0
  81. package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.cjs.js +2 -0
  82. package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.cjs.js.map +1 -0
  83. package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.esm.js +32 -0
  84. package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.esm.js.map +1 -0
  85. package/dist/node_modules/jose/dist/browser/lib/is_disjoint.cjs.js +2 -0
  86. package/dist/node_modules/jose/dist/browser/lib/is_disjoint.cjs.js.map +1 -0
  87. package/dist/node_modules/jose/dist/browser/lib/is_disjoint.esm.js +25 -0
  88. package/dist/node_modules/jose/dist/browser/lib/is_disjoint.esm.js.map +1 -0
  89. package/dist/node_modules/jose/dist/browser/lib/is_jwk.cjs.js +2 -0
  90. package/dist/node_modules/jose/dist/browser/lib/is_jwk.cjs.js.map +1 -0
  91. package/dist/node_modules/jose/dist/browser/lib/is_jwk.esm.js +20 -0
  92. package/dist/node_modules/jose/dist/browser/lib/is_jwk.esm.js.map +1 -0
  93. package/dist/node_modules/jose/dist/browser/lib/is_object.cjs.js +2 -0
  94. package/dist/node_modules/jose/dist/browser/lib/is_object.cjs.js.map +1 -0
  95. package/dist/node_modules/jose/dist/browser/lib/is_object.esm.js +20 -0
  96. package/dist/node_modules/jose/dist/browser/lib/is_object.esm.js.map +1 -0
  97. package/dist/node_modules/jose/dist/browser/lib/secs.cjs.js +2 -0
  98. package/dist/node_modules/jose/dist/browser/lib/secs.cjs.js.map +1 -0
  99. package/dist/node_modules/jose/dist/browser/lib/secs.esm.js +59 -0
  100. package/dist/node_modules/jose/dist/browser/lib/secs.esm.js.map +1 -0
  101. package/dist/node_modules/jose/dist/browser/lib/validate_crit.cjs.js +2 -0
  102. package/dist/node_modules/jose/dist/browser/lib/validate_crit.cjs.js.map +1 -0
  103. package/dist/node_modules/jose/dist/browser/lib/validate_crit.esm.js +34 -0
  104. package/dist/node_modules/jose/dist/browser/lib/validate_crit.esm.js.map +1 -0
  105. package/dist/node_modules/jose/dist/browser/runtime/asn1.cjs.js +2 -0
  106. package/dist/node_modules/jose/dist/browser/runtime/asn1.cjs.js.map +1 -0
  107. package/dist/node_modules/jose/dist/browser/runtime/asn1.esm.js +103 -0
  108. package/dist/node_modules/jose/dist/browser/runtime/asn1.esm.js.map +1 -0
  109. package/dist/node_modules/jose/dist/browser/runtime/base64url.cjs.js +2 -0
  110. package/dist/node_modules/jose/dist/browser/runtime/base64url.cjs.js.map +1 -0
  111. package/dist/node_modules/jose/dist/browser/runtime/base64url.esm.js +43 -0
  112. package/dist/node_modules/jose/dist/browser/runtime/base64url.esm.js.map +1 -0
  113. package/dist/node_modules/jose/dist/browser/runtime/check_key_length.cjs.js +2 -0
  114. package/dist/node_modules/jose/dist/browser/runtime/check_key_length.cjs.js.map +1 -0
  115. package/dist/node_modules/jose/dist/browser/runtime/check_key_length.esm.js +12 -0
  116. package/dist/node_modules/jose/dist/browser/runtime/check_key_length.esm.js.map +1 -0
  117. package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.cjs.js +2 -0
  118. package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.cjs.js.map +1 -0
  119. package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.esm.js +25 -0
  120. package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.esm.js.map +1 -0
  121. package/dist/node_modules/jose/dist/browser/runtime/is_key_like.cjs.js +2 -0
  122. package/dist/node_modules/jose/dist/browser/runtime/is_key_like.cjs.js.map +1 -0
  123. package/dist/node_modules/jose/dist/browser/runtime/is_key_like.esm.js +13 -0
  124. package/dist/node_modules/jose/dist/browser/runtime/is_key_like.esm.js.map +1 -0
  125. package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.cjs.js +2 -0
  126. package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.cjs.js.map +1 -0
  127. package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.esm.js +107 -0
  128. package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.esm.js.map +1 -0
  129. package/dist/node_modules/jose/dist/browser/runtime/normalize_key.cjs.js +2 -0
  130. package/dist/node_modules/jose/dist/browser/runtime/normalize_key.cjs.js.map +1 -0
  131. package/dist/node_modules/jose/dist/browser/runtime/normalize_key.esm.js +71 -0
  132. package/dist/node_modules/jose/dist/browser/runtime/normalize_key.esm.js.map +1 -0
  133. package/dist/node_modules/jose/dist/browser/runtime/sign.cjs.js +2 -0
  134. package/dist/node_modules/jose/dist/browser/runtime/sign.cjs.js.map +1 -0
  135. package/dist/node_modules/jose/dist/browser/runtime/sign.esm.js +14 -0
  136. package/dist/node_modules/jose/dist/browser/runtime/sign.esm.js.map +1 -0
  137. package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.cjs.js +2 -0
  138. package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.cjs.js.map +1 -0
  139. package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.esm.js +32 -0
  140. package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.esm.js.map +1 -0
  141. package/dist/node_modules/jose/dist/browser/runtime/webcrypto.cjs.js +2 -0
  142. package/dist/node_modules/jose/dist/browser/runtime/webcrypto.cjs.js.map +1 -0
  143. package/dist/node_modules/jose/dist/browser/runtime/webcrypto.esm.js +7 -0
  144. package/dist/node_modules/jose/dist/browser/runtime/webcrypto.esm.js.map +1 -0
  145. package/dist/node_modules/jose/dist/browser/util/errors.cjs.js +2 -0
  146. package/dist/node_modules/jose/dist/browser/util/errors.cjs.js.map +1 -0
  147. package/dist/node_modules/jose/dist/browser/util/errors.esm.js +131 -0
  148. package/dist/node_modules/jose/dist/browser/util/errors.esm.js.map +1 -0
  149. package/dist/node_modules/react-dom/client.cjs.js +2 -0
  150. package/dist/node_modules/react-dom/client.cjs.js.map +1 -0
  151. package/dist/node_modules/react-dom/client.esm.js +21 -0
  152. package/dist/node_modules/react-dom/client.esm.js.map +1 -0
  153. package/dist/nuxt.cjs.js +2 -0
  154. package/dist/nuxt.cjs.js.map +1 -0
  155. package/dist/nuxt.esm.js +10 -0
  156. package/dist/nuxt.esm.js.map +1 -0
  157. package/dist/services/chatService.cjs.js +2 -0
  158. package/dist/services/chatService.cjs.js.map +1 -0
  159. package/dist/services/chatService.esm.js +482 -0
  160. package/dist/services/chatService.esm.js.map +1 -0
  161. package/dist/services/dialogflowClient.cjs.js +2 -0
  162. package/dist/services/dialogflowClient.cjs.js.map +1 -0
  163. package/dist/services/dialogflowClient.esm.js +282 -0
  164. package/dist/services/dialogflowClient.esm.js.map +1 -0
  165. package/dist/services/sessionManager.cjs.js +2 -0
  166. package/dist/services/sessionManager.cjs.js.map +1 -0
  167. package/dist/services/sessionManager.esm.js +48 -0
  168. package/dist/services/sessionManager.esm.js.map +1 -0
  169. package/dist/styles.css +1 -596
  170. package/dist/utils/frameworkDetector.cjs.js +2 -0
  171. package/dist/utils/frameworkDetector.cjs.js.map +1 -0
  172. package/dist/utils/frameworkDetector.esm.js +125 -0
  173. package/dist/utils/frameworkDetector.esm.js.map +1 -0
  174. package/dist/utils/sanitize.cjs.js +2 -0
  175. package/dist/utils/sanitize.cjs.js.map +1 -0
  176. package/dist/utils/sanitize.d.ts +25 -0
  177. package/dist/utils/sanitize.d.ts.map +1 -0
  178. package/dist/utils/sanitize.esm.js +52 -0
  179. package/dist/utils/sanitize.esm.js.map +1 -0
  180. package/dist/utils/ssr.d.ts +35 -0
  181. package/dist/utils/ssr.d.ts.map +1 -0
  182. package/dist/vue.cjs.js +2 -1
  183. package/dist/vue.cjs.js.map +1 -0
  184. package/dist/vue.esm.js +10 -1
  185. package/dist/vue.esm.js.map +1 -0
  186. package/package.json +30 -23
  187. package/dist/index.cjs.js.LICENSE.txt +0 -27
  188. package/dist/index.esm.js.LICENSE.txt +0 -27
  189. package/dist/index.js +0 -2
  190. package/dist/index.js.LICENSE.txt +0 -9
  191. package/dist/index.umd.js +0 -2
  192. package/dist/index.umd.js.LICENSE.txt +0 -27
  193. package/dist/react.cjs.js +0 -2
  194. package/dist/react.cjs.js.LICENSE.txt +0 -9
  195. package/dist/react.esm.js +0 -2
  196. package/dist/react.esm.js.LICENSE.txt +0 -9
  197. package/dist/vue/ChatWidgetWrapper.d.ts +0 -182
  198. package/dist/vue/ChatWidgetWrapper.d.ts.map +0 -1
  199. package/dist/vue/index.d.ts +0 -191
  200. package/dist/vue/index.d.ts.map +0 -1
  201. package/dist/vue.js +0 -2
  202. package/dist/vue.js.LICENSE.txt +0 -39
@@ -0,0 +1,915 @@
1
+ import { createDialogflowSession, sendDialogflowMessage } from "../services/dialogflowClient.esm.js";
2
+ import { createChatService, ChatResolvedError } from "../services/chatService.esm.js";
3
+ class WidgetStateManager {
4
+ constructor(config) {
5
+ this.listeners = /* @__PURE__ */ new Set();
6
+ this.chatMode = "ai";
7
+ this.chatId = null;
8
+ this.supportSessionId = null;
9
+ this.chatService = null;
10
+ this.collectingUserInfo = false;
11
+ this.userInfoStep = null;
12
+ this.collectedUserName = "";
13
+ this.collectedUserEmail = "";
14
+ this.collectedUserMobile = "";
15
+ this.wsConnected = false;
16
+ this.agentTyping = false;
17
+ this.currentAgent = { name: "Agent" };
18
+ this.isConnectingToAgent = false;
19
+ this.agentAccepted = false;
20
+ this.chatResolved = false;
21
+ this.historyLoaded = null;
22
+ this.typingTimeout = null;
23
+ this.agentTypingTimeout = null;
24
+ this.config = config;
25
+ this.state = {
26
+ isOpen: false,
27
+ showWelcomePopup: false,
28
+ messages: [],
29
+ inputValue: "",
30
+ isLoading: false,
31
+ error: null,
32
+ sessionId: null,
33
+ chatMode: "ai"
34
+ };
35
+ this.chatService = createChatService({
36
+ baseUrl: this.config.backendBaseUrl || "http://localhost:8012",
37
+ wsUrl: this.config.backendWsUrl || "ws://localhost:8012",
38
+ debug: this.config.debug || false
39
+ });
40
+ if (typeof window !== "undefined" && window.localStorage) {
41
+ const savedMode = localStorage.getItem("blockspark_chat_mode");
42
+ this.chatMode = savedMode === "HUMAN" ? "human" : "ai";
43
+ this.state.chatMode = this.chatMode;
44
+ this.chatId = localStorage.getItem("blockspark_chat_id");
45
+ this.supportSessionId = localStorage.getItem("blockspark_session_id");
46
+ }
47
+ }
48
+ /**
49
+ * Subscribe to state changes
50
+ */
51
+ subscribe(listener) {
52
+ this.listeners.add(listener);
53
+ return () => {
54
+ this.listeners.delete(listener);
55
+ };
56
+ }
57
+ /**
58
+ * Get current state
59
+ */
60
+ getState() {
61
+ return { ...this.state };
62
+ }
63
+ /**
64
+ * Update state and notify listeners
65
+ */
66
+ setState(updates) {
67
+ this.state = { ...this.state, ...updates };
68
+ this.listeners.forEach((listener) => listener(this.getState()));
69
+ }
70
+ /**
71
+ * Update configuration
72
+ */
73
+ updateConfig(config) {
74
+ this.config = { ...this.config, ...config };
75
+ }
76
+ /**
77
+ * Open chat
78
+ */
79
+ async openChat() {
80
+ this.setState({ isOpen: true });
81
+ if (this.state.showWelcomePopup) {
82
+ this.setState({ showWelcomePopup: false });
83
+ }
84
+ if (this.state.chatMode === "ai" && !this.state.sessionId && this.config.dfProjectId && this.config.dfAgentId) {
85
+ try {
86
+ this.setState({ isLoading: true });
87
+ const dialogflowConfig = {
88
+ dfProjectId: this.config.dfProjectId,
89
+ dfLocation: this.config.dfLocation || "us-central1",
90
+ dfAgentId: this.config.dfAgentId,
91
+ serviceAccountKey: this.config.serviceAccountKey,
92
+ accessToken: this.config.accessToken,
93
+ languageCode: this.config.languageCode || "en"
94
+ };
95
+ const session = await createDialogflowSession(dialogflowConfig);
96
+ this.setState({
97
+ sessionId: session.session_id,
98
+ isLoading: false
99
+ });
100
+ if (session.message) {
101
+ const welcomeMessage = {
102
+ id: `welcome-${Date.now()}`,
103
+ text: session.message,
104
+ sender: "bot",
105
+ timestamp: /* @__PURE__ */ new Date(),
106
+ richContent: session.richContent
107
+ };
108
+ this.setState({
109
+ messages: [welcomeMessage]
110
+ });
111
+ }
112
+ } catch (error) {
113
+ console.error("Error initializing Dialogflow session:", error);
114
+ this.setState({
115
+ isLoading: false,
116
+ error: error.message || "Failed to initialize chat"
117
+ });
118
+ const fallbackMessage = {
119
+ id: `fallback-${Date.now()}`,
120
+ text: this.config.fallbackWelcomeMessage || "Hello! How can I help you today?",
121
+ sender: "bot",
122
+ timestamp: /* @__PURE__ */ new Date()
123
+ };
124
+ this.setState({
125
+ messages: [fallbackMessage]
126
+ });
127
+ }
128
+ }
129
+ }
130
+ /**
131
+ * Close chat
132
+ */
133
+ closeChat() {
134
+ this.setState({ isOpen: false });
135
+ }
136
+ /**
137
+ * Close welcome popup
138
+ */
139
+ closeWelcomePopup() {
140
+ this.setState({ showWelcomePopup: false });
141
+ }
142
+ /**
143
+ * Toggle chat
144
+ */
145
+ toggleChat() {
146
+ const willBeOpen = !this.state.isOpen;
147
+ this.setState({ isOpen: willBeOpen });
148
+ if (willBeOpen && this.state.showWelcomePopup) {
149
+ this.setState({ showWelcomePopup: false });
150
+ }
151
+ }
152
+ /**
153
+ * Set input value
154
+ */
155
+ setInputValue(value) {
156
+ this.setState({ inputValue: value });
157
+ }
158
+ /**
159
+ * Clear error
160
+ */
161
+ clearError() {
162
+ this.setState({ error: null });
163
+ }
164
+ /**
165
+ * Send message
166
+ */
167
+ async sendMessage(text, skipUserMessage = false) {
168
+ if (!text.trim() || this.state.isLoading) {
169
+ return;
170
+ }
171
+ if (this.collectingUserInfo) {
172
+ const userMessage = {
173
+ id: `user-${Date.now()}`,
174
+ text: text.trim(),
175
+ sender: "user",
176
+ timestamp: /* @__PURE__ */ new Date()
177
+ };
178
+ this.setState({
179
+ messages: [...this.state.messages, userMessage],
180
+ inputValue: "",
181
+ isLoading: false,
182
+ error: null
183
+ });
184
+ await this.handleUserInfoCollection(text);
185
+ return;
186
+ }
187
+ if (!skipUserMessage) {
188
+ const userMessage = {
189
+ id: `user-${Date.now()}`,
190
+ text: text.trim(),
191
+ sender: "user",
192
+ timestamp: /* @__PURE__ */ new Date()
193
+ };
194
+ this.setState({
195
+ messages: [...this.state.messages, userMessage],
196
+ inputValue: "",
197
+ isLoading: true,
198
+ error: null
199
+ });
200
+ } else {
201
+ this.setState({
202
+ inputValue: "",
203
+ isLoading: true,
204
+ error: null
205
+ });
206
+ }
207
+ try {
208
+ if (this.state.chatMode === "human") {
209
+ await this.sendHumanMessage(text);
210
+ } else {
211
+ await this.sendAIMessage(text);
212
+ }
213
+ } catch (error) {
214
+ console.error("Error sending message:", error);
215
+ if (error instanceof ChatResolvedError || error?.name === "ChatResolvedError" || error?.message === "chat_resolved") {
216
+ this.enterResolvedState(this.chatId);
217
+ return;
218
+ }
219
+ const errorMessage = {
220
+ id: `error-${Date.now()}`,
221
+ text: this.config.debug ? `Error: ${error.message || "Failed to send message"}` : error.message?.includes("CORS") || error.message?.includes("Failed to fetch") ? "Unable to connect to Dialogflow. Please check your configuration and network." : "Sorry, I'm having trouble processing your message. Please try again.",
222
+ sender: "bot",
223
+ timestamp: /* @__PURE__ */ new Date()
224
+ };
225
+ this.setState({
226
+ messages: [...this.state.messages, errorMessage],
227
+ error: error.message || "Failed to send message",
228
+ isLoading: false
229
+ });
230
+ }
231
+ }
232
+ /**
233
+ * Send message to Dialogflow
234
+ */
235
+ async sendAIMessage(text) {
236
+ if (!this.config.dfProjectId || !this.config.dfAgentId) {
237
+ throw new Error("Dialogflow configuration is missing");
238
+ }
239
+ const dialogflowConfig = {
240
+ dfProjectId: this.config.dfProjectId,
241
+ dfLocation: this.config.dfLocation || "us-central1",
242
+ dfAgentId: this.config.dfAgentId,
243
+ serviceAccountKey: this.config.serviceAccountKey,
244
+ accessToken: this.config.accessToken,
245
+ languageCode: this.config.languageCode || "en"
246
+ };
247
+ if (!this.state.sessionId) {
248
+ const session = await createDialogflowSession(dialogflowConfig);
249
+ this.setState({ sessionId: session.session_id });
250
+ }
251
+ if (this.config.debug) {
252
+ console.log("Sending message to Dialogflow:", {
253
+ message: text,
254
+ sessionId: this.state.sessionId,
255
+ hasConfig: !!dialogflowConfig
256
+ });
257
+ }
258
+ const response = await sendDialogflowMessage(
259
+ text,
260
+ this.state.sessionId,
261
+ dialogflowConfig
262
+ );
263
+ if (this.config.debug) {
264
+ console.log("Dialogflow response:", {
265
+ response: response.response,
266
+ hasRichContent: !!response.richContent,
267
+ richContent: response.richContent
268
+ });
269
+ }
270
+ if (response.handoff === true) {
271
+ const botMessage2 = {
272
+ id: `bot-${Date.now()}`,
273
+ text: response.response || this.config.fallbackWelcomeMessage || "No response",
274
+ sender: "bot",
275
+ timestamp: /* @__PURE__ */ new Date(),
276
+ richContent: response.richContent
277
+ };
278
+ this.setState({
279
+ messages: [...this.state.messages, botMessage2],
280
+ isLoading: false
281
+ });
282
+ this.startUserInfoCollection();
283
+ return;
284
+ }
285
+ const botMessage = {
286
+ id: `bot-${Date.now()}`,
287
+ text: response.response || this.config.fallbackWelcomeMessage || "No response",
288
+ sender: "bot",
289
+ timestamp: /* @__PURE__ */ new Date(),
290
+ richContent: response.richContent
291
+ };
292
+ this.setState({
293
+ messages: [...this.state.messages, botMessage],
294
+ isLoading: false
295
+ });
296
+ }
297
+ /**
298
+ * Send message to human support
299
+ */
300
+ async sendHumanMessage(text) {
301
+ if (!this.chatId || !this.supportSessionId) {
302
+ const errorMessage = {
303
+ id: `error-${Date.now()}`,
304
+ text: "Chat session not initialized. Please try again.",
305
+ sender: "bot",
306
+ timestamp: /* @__PURE__ */ new Date()
307
+ };
308
+ this.setState({
309
+ messages: [...this.state.messages, errorMessage],
310
+ isLoading: false
311
+ });
312
+ return;
313
+ }
314
+ if (!this.chatService) {
315
+ throw new Error("Chat service not initialized");
316
+ }
317
+ this.chatService.sendTypingIndicator("typing_stop");
318
+ if (this.typingTimeout) {
319
+ clearTimeout(this.typingTimeout);
320
+ this.typingTimeout = null;
321
+ }
322
+ try {
323
+ const sentViaWs = this.chatService.sendMessageViaWebSocket(text.trim());
324
+ if (!sentViaWs) {
325
+ await this.chatService.sendMessageToAgent(this.chatId, this.supportSessionId, text.trim());
326
+ }
327
+ this.setState({ isLoading: false });
328
+ } catch (error) {
329
+ if (error instanceof ChatResolvedError || error?.name === "ChatResolvedError" || error?.message === "chat_resolved") {
330
+ this.enterResolvedState(this.chatId);
331
+ return;
332
+ }
333
+ if (error.message?.includes("Chat not found") || error.message?.includes("unauthorized") || error.message?.includes("401") || error.message?.includes("404")) {
334
+ if (this.config.debug) {
335
+ console.log("⚠️ Chat expired. Re-initializing...");
336
+ }
337
+ this.chatId = null;
338
+ this.supportSessionId = null;
339
+ if (typeof window !== "undefined" && window.localStorage) {
340
+ localStorage.removeItem("blockspark_chat_id");
341
+ localStorage.removeItem("blockspark_session_id");
342
+ }
343
+ try {
344
+ const newSession = await this.chatService.startSupportChat(
345
+ this.state.sessionId || null,
346
+ null,
347
+ null,
348
+ null
349
+ );
350
+ this.chatId = newSession.chat_id;
351
+ this.supportSessionId = newSession.session_id;
352
+ if (typeof window !== "undefined" && window.localStorage) {
353
+ localStorage.setItem("blockspark_chat_id", this.chatId);
354
+ localStorage.setItem("blockspark_session_id", this.supportSessionId);
355
+ }
356
+ if (this.chatId && this.supportSessionId) {
357
+ await this.chatService.sendMessageToAgent(
358
+ this.chatId,
359
+ this.supportSessionId,
360
+ text.trim()
361
+ );
362
+ }
363
+ this.setState({ isLoading: false });
364
+ return;
365
+ } catch (retryError) {
366
+ if (retryError instanceof ChatResolvedError || retryError?.message === "chat_resolved") {
367
+ this.enterResolvedState(this.chatId);
368
+ return;
369
+ }
370
+ throw retryError;
371
+ }
372
+ } else {
373
+ throw error;
374
+ }
375
+ }
376
+ }
377
+ /**
378
+ * Switch to human mode
379
+ */
380
+ switchToHumanMode() {
381
+ this.chatMode = "human";
382
+ this.setState({ chatMode: "human" });
383
+ if (typeof window !== "undefined" && window.localStorage) {
384
+ localStorage.setItem("blockspark_chat_mode", "HUMAN");
385
+ }
386
+ }
387
+ /**
388
+ * Switch to AI mode
389
+ */
390
+ switchToBotMode() {
391
+ this.chatMode = "ai";
392
+ this.setState({ chatMode: "ai" });
393
+ if (typeof window !== "undefined" && window.localStorage) {
394
+ localStorage.setItem("blockspark_chat_mode", "BOT");
395
+ }
396
+ }
397
+ /**
398
+ * Initialize welcome popup
399
+ */
400
+ initializeWelcomePopup() {
401
+ if (this.config.showWelcomePopup !== false) {
402
+ const delay = this.config.welcomePopupDelay || 1500;
403
+ setTimeout(() => {
404
+ if (!this.state.isOpen) {
405
+ this.setState({ showWelcomePopup: true });
406
+ }
407
+ }, delay);
408
+ }
409
+ }
410
+ /**
411
+ * Start user info collection for handoff
412
+ */
413
+ startUserInfoCollection() {
414
+ this.collectingUserInfo = true;
415
+ this.userInfoStep = "name";
416
+ this.collectedUserName = "";
417
+ this.collectedUserEmail = "";
418
+ this.collectedUserMobile = "";
419
+ const namePrompt = {
420
+ id: `prompt-${Date.now()}`,
421
+ text: "To connect you with a human agent, I'll need some information. Please provide your name:",
422
+ sender: "bot",
423
+ timestamp: /* @__PURE__ */ new Date()
424
+ };
425
+ this.setState({
426
+ messages: [...this.state.messages, namePrompt]
427
+ });
428
+ }
429
+ /**
430
+ * Handle user info collection
431
+ */
432
+ async handleUserInfoCollection(text) {
433
+ if (this.userInfoStep === "name") {
434
+ const name = text.trim();
435
+ this.collectedUserName = name;
436
+ this.userInfoStep = "email";
437
+ const emailPrompt = {
438
+ id: `prompt-${Date.now()}`,
439
+ text: "Thank you! Now please provide your email address:",
440
+ sender: "bot",
441
+ timestamp: /* @__PURE__ */ new Date()
442
+ };
443
+ this.setState({
444
+ messages: [...this.state.messages, emailPrompt],
445
+ inputValue: ""
446
+ });
447
+ return;
448
+ } else if (this.userInfoStep === "email") {
449
+ const email = text.trim();
450
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
451
+ if (!emailRegex.test(email)) {
452
+ const invalidEmailMessage = {
453
+ id: `prompt-${Date.now()}`,
454
+ text: "Please provide a valid email address:",
455
+ sender: "bot",
456
+ timestamp: /* @__PURE__ */ new Date()
457
+ };
458
+ this.setState({
459
+ messages: [...this.state.messages, invalidEmailMessage],
460
+ inputValue: ""
461
+ });
462
+ return;
463
+ }
464
+ this.collectedUserEmail = email;
465
+ this.userInfoStep = "mobile";
466
+ const mobilePrompt = {
467
+ id: `prompt-${Date.now()}`,
468
+ text: "Thank you! Now please provide your mobile number:",
469
+ sender: "bot",
470
+ timestamp: /* @__PURE__ */ new Date()
471
+ };
472
+ this.setState({
473
+ messages: [...this.state.messages, mobilePrompt],
474
+ inputValue: ""
475
+ });
476
+ return;
477
+ } else if (this.userInfoStep === "mobile") {
478
+ const mobile = text.trim();
479
+ const mobileRegex = /^[\+]?[(]?[0-9]{1,4}[)]?[-\s\.]?[(]?[0-9]{1,4}[)]?[-\s\.]?[0-9]{1,9}$/;
480
+ if (!mobileRegex.test(mobile) || mobile.length < 10) {
481
+ const invalidMobileMessage = {
482
+ id: `prompt-${Date.now()}`,
483
+ text: "Please provide a valid mobile number (e.g., +1234567890):",
484
+ sender: "bot",
485
+ timestamp: /* @__PURE__ */ new Date()
486
+ };
487
+ this.setState({
488
+ messages: [...this.state.messages, invalidMobileMessage],
489
+ inputValue: ""
490
+ });
491
+ return;
492
+ }
493
+ this.collectedUserMobile = mobile;
494
+ this.collectingUserInfo = false;
495
+ this.userInfoStep = null;
496
+ await this.handleHandoff(this.collectedUserName, this.collectedUserEmail, mobile);
497
+ this.setState({ inputValue: "" });
498
+ }
499
+ }
500
+ /**
501
+ * Handle handoff from Dialogflow to human support
502
+ */
503
+ async handleHandoff(customerName, customerEmail, customerMobile) {
504
+ if (!this.chatService) {
505
+ throw new Error("Chat service not initialized");
506
+ }
507
+ try {
508
+ this.isConnectingToAgent = true;
509
+ const dialogflowSessionId = this.state.sessionId;
510
+ const session = await this.chatService.ensureChatInitialized(
511
+ this.chatId,
512
+ this.supportSessionId,
513
+ dialogflowSessionId || null,
514
+ customerName || null,
515
+ customerEmail || null,
516
+ customerMobile || null
517
+ );
518
+ if (!session || !session.chat_id) {
519
+ throw new Error("Failed to initialize chat session");
520
+ }
521
+ const currentChatId = session.chat_id;
522
+ const currentSupportSessionId = session.session_id;
523
+ if (currentChatId !== this.chatId) {
524
+ this.chatId = currentChatId;
525
+ this.supportSessionId = currentSupportSessionId;
526
+ if (typeof window !== "undefined" && window.localStorage) {
527
+ localStorage.setItem("blockspark_chat_id", this.chatId);
528
+ localStorage.setItem("blockspark_session_id", this.supportSessionId);
529
+ }
530
+ if (this.config.debug) {
531
+ console.log("✅ Chat initialized:", { chatId: currentChatId, sessionId: currentSupportSessionId });
532
+ }
533
+ }
534
+ try {
535
+ await this.chatService.requestHandoff(
536
+ currentChatId,
537
+ currentSupportSessionId,
538
+ "Customer requested human agent",
539
+ dialogflowSessionId || null,
540
+ customerName || null,
541
+ customerEmail || null,
542
+ customerMobile || null
543
+ );
544
+ if (this.config.debug) {
545
+ console.log("✅ Handoff requested successfully");
546
+ }
547
+ } catch (handoffError) {
548
+ if (handoffError.message?.includes("Invalid chat_id") || handoffError.message?.includes("Chat not found") || handoffError.message?.includes("unauthorized") || handoffError.message?.includes("400") || handoffError.message?.includes("401") || handoffError.message?.includes("404") || handoffError.message?.includes("expired")) {
549
+ if (this.config.debug) {
550
+ console.log("⚠️ Chat expired or not found. Re-initializing chat...");
551
+ }
552
+ this.chatId = null;
553
+ this.supportSessionId = null;
554
+ if (typeof window !== "undefined" && window.localStorage) {
555
+ localStorage.removeItem("blockspark_chat_id");
556
+ localStorage.removeItem("blockspark_session_id");
557
+ }
558
+ const newSession = await this.chatService.startSupportChat(
559
+ dialogflowSessionId || null,
560
+ customerName || null,
561
+ customerEmail || null,
562
+ customerMobile || null
563
+ );
564
+ if (!newSession || !newSession.chat_id) {
565
+ throw new Error("Failed to re-initialize chat session");
566
+ }
567
+ this.chatId = newSession.chat_id;
568
+ this.supportSessionId = newSession.session_id;
569
+ if (typeof window !== "undefined" && window.localStorage) {
570
+ localStorage.setItem("blockspark_chat_id", this.chatId);
571
+ localStorage.setItem("blockspark_session_id", this.supportSessionId);
572
+ }
573
+ await this.chatService.requestHandoff(
574
+ this.chatId,
575
+ this.supportSessionId,
576
+ "Customer requested human agent",
577
+ dialogflowSessionId || null,
578
+ customerName || null,
579
+ customerEmail || null,
580
+ customerMobile || null
581
+ );
582
+ if (this.config.debug) {
583
+ console.log("✅ Handoff requested successfully after retry");
584
+ }
585
+ } else {
586
+ throw handoffError;
587
+ }
588
+ }
589
+ this.switchToHumanMode();
590
+ this.chatResolved = false;
591
+ this.agentAccepted = false;
592
+ const connectingMessage = {
593
+ id: `connecting-${Date.now()}`,
594
+ text: "Connecting you to a human agent...",
595
+ sender: "bot",
596
+ timestamp: /* @__PURE__ */ new Date()
597
+ };
598
+ this.setState({
599
+ messages: [...this.state.messages, connectingMessage]
600
+ });
601
+ if (currentChatId && currentSupportSessionId) {
602
+ this.chatService.connectWebSocket(
603
+ currentChatId,
604
+ currentSupportSessionId,
605
+ (message) => {
606
+ this.handleWebSocketMessage(message);
607
+ },
608
+ (connected) => {
609
+ this.wsConnected = connected;
610
+ }
611
+ );
612
+ }
613
+ this.isConnectingToAgent = false;
614
+ } catch (error) {
615
+ console.error("Error handling handoff:", error);
616
+ const errorMessage = {
617
+ id: `error-${Date.now()}`,
618
+ text: this.config.debug ? `Handoff error: ${error.message}` : "Failed to connect to agent. Please try again.",
619
+ sender: "bot",
620
+ timestamp: /* @__PURE__ */ new Date()
621
+ };
622
+ this.setState({
623
+ messages: [...this.state.messages, errorMessage]
624
+ });
625
+ this.isConnectingToAgent = false;
626
+ }
627
+ }
628
+ /**
629
+ * Handle WebSocket messages
630
+ */
631
+ handleWebSocketMessage(message) {
632
+ switch (message.type) {
633
+ case "message":
634
+ if (message.content) {
635
+ if (message.sender_type === "agent" || !message.sender_type) {
636
+ const agentMessage = {
637
+ id: message.id || `agent-${Date.now()}`,
638
+ text: message.content,
639
+ sender: "agent",
640
+ timestamp: new Date(message.timestamp || Date.now())
641
+ };
642
+ const existingIds2 = new Set(this.state.messages.map((m) => m.id));
643
+ if (!existingIds2.has(agentMessage.id)) {
644
+ this.setState({
645
+ messages: [...this.state.messages, agentMessage]
646
+ });
647
+ }
648
+ this.agentTyping = false;
649
+ if (this.agentTypingTimeout) {
650
+ clearTimeout(this.agentTypingTimeout);
651
+ this.agentTypingTimeout = null;
652
+ }
653
+ }
654
+ }
655
+ break;
656
+ case "typing_start":
657
+ if (message.sender_type === "agent") {
658
+ this.agentTyping = true;
659
+ if (this.agentTypingTimeout) {
660
+ clearTimeout(this.agentTypingTimeout);
661
+ }
662
+ this.agentTypingTimeout = setTimeout(() => {
663
+ this.agentTyping = false;
664
+ }, 3e3);
665
+ }
666
+ break;
667
+ case "typing_stop":
668
+ if (message.sender_type === "agent") {
669
+ this.agentTyping = false;
670
+ if (this.agentTypingTimeout) {
671
+ clearTimeout(this.agentTypingTimeout);
672
+ this.agentTypingTimeout = null;
673
+ }
674
+ }
675
+ break;
676
+ case "agent_changed":
677
+ if (message.to_agent) {
678
+ this.currentAgent = {
679
+ id: message.to_agent_id,
680
+ name: message.to_agent
681
+ };
682
+ const systemMessage = {
683
+ id: `system-${Date.now()}`,
684
+ text: message.from_agent ? `Chat has been transferred from ${message.from_agent} to ${message.to_agent}` : `Chat has been transferred to ${message.to_agent}`,
685
+ sender: "bot",
686
+ timestamp: /* @__PURE__ */ new Date()
687
+ };
688
+ this.setState({
689
+ messages: [...this.state.messages, systemMessage]
690
+ });
691
+ }
692
+ break;
693
+ case "agent_accepted":
694
+ this.agentAccepted = true;
695
+ this.isConnectingToAgent = false;
696
+ const acceptedMessage = {
697
+ id: message.id || `agent-accepted-${Date.now()}`,
698
+ text: "You can chat now, the agent has accepted your request.",
699
+ sender: "bot",
700
+ timestamp: message.timestamp ? new Date(message.timestamp) : /* @__PURE__ */ new Date()
701
+ };
702
+ const existingIds = new Set(this.state.messages.map((m) => m.id));
703
+ if (!existingIds.has(acceptedMessage.id)) {
704
+ this.setState({
705
+ messages: [...this.state.messages, acceptedMessage]
706
+ });
707
+ }
708
+ if (message.to_agent) {
709
+ this.currentAgent = {
710
+ name: message.to_agent,
711
+ id: message.to_agent_id
712
+ };
713
+ }
714
+ break;
715
+ case "chat_resolved":
716
+ case "chat_ended":
717
+ this.enterResolvedState(message.chat_id || null);
718
+ break;
719
+ case "chat_info":
720
+ if (message.status === "active") {
721
+ this.isConnectingToAgent = false;
722
+ this.agentAccepted = true;
723
+ } else if (message.status === "resolved" || message.status === "ended") {
724
+ this.enterResolvedState(message.chat_id || null);
725
+ }
726
+ if (message.agent_id) {
727
+ this.currentAgent = {
728
+ ...this.currentAgent,
729
+ id: message.agent_id
730
+ };
731
+ }
732
+ break;
733
+ case "error":
734
+ console.error("WebSocket error:", message.error);
735
+ const errorMessage = {
736
+ id: `error-${Date.now()}`,
737
+ text: message.error || "An error occurred. Please try again.",
738
+ sender: "bot",
739
+ timestamp: /* @__PURE__ */ new Date()
740
+ };
741
+ this.setState({
742
+ messages: [...this.state.messages, errorMessage]
743
+ });
744
+ break;
745
+ }
746
+ }
747
+ /**
748
+ * Enter resolved state
749
+ */
750
+ enterResolvedState(resolvedChatId) {
751
+ this.chatResolved = true;
752
+ this.isConnectingToAgent = false;
753
+ this.agentAccepted = false;
754
+ this.agentTyping = false;
755
+ if (this.agentTypingTimeout) {
756
+ clearTimeout(this.agentTypingTimeout);
757
+ this.agentTypingTimeout = null;
758
+ }
759
+ if (this.chatService) {
760
+ this.chatService.disconnectWebSocket();
761
+ }
762
+ this.chatId = null;
763
+ this.supportSessionId = null;
764
+ if (typeof window !== "undefined" && window.localStorage) {
765
+ localStorage.removeItem("blockspark_chat_id");
766
+ localStorage.removeItem("blockspark_session_id");
767
+ }
768
+ const thankYouMessage = {
769
+ id: `resolved-${Date.now()}`,
770
+ text: "Thank you for contacting us!",
771
+ sender: "bot",
772
+ timestamp: /* @__PURE__ */ new Date()
773
+ };
774
+ this.setState({
775
+ messages: [...this.state.messages, thankYouMessage]
776
+ });
777
+ setTimeout(async () => {
778
+ this.switchToBotMode();
779
+ this.chatResolved = false;
780
+ this.setState({
781
+ messages: [],
782
+ sessionId: null
783
+ // Clear session ID to force recreation
784
+ });
785
+ this.collectingUserInfo = false;
786
+ this.userInfoStep = null;
787
+ this.collectedUserName = "";
788
+ this.collectedUserEmail = "";
789
+ this.collectedUserMobile = "";
790
+ if (this.config.dfProjectId && this.config.dfAgentId && this.state.isOpen) {
791
+ try {
792
+ this.setState({ isLoading: true });
793
+ const dialogflowConfig = {
794
+ dfProjectId: this.config.dfProjectId,
795
+ dfLocation: this.config.dfLocation || "us-central1",
796
+ dfAgentId: this.config.dfAgentId,
797
+ serviceAccountKey: this.config.serviceAccountKey,
798
+ accessToken: this.config.accessToken,
799
+ languageCode: this.config.languageCode || "en"
800
+ };
801
+ const session = await createDialogflowSession(dialogflowConfig);
802
+ this.setState({
803
+ sessionId: session.session_id,
804
+ isLoading: false
805
+ });
806
+ if (session.message) {
807
+ const welcomeMessage = {
808
+ id: `welcome-${Date.now()}`,
809
+ text: session.message,
810
+ sender: "bot",
811
+ timestamp: /* @__PURE__ */ new Date(),
812
+ richContent: session.richContent
813
+ };
814
+ this.setState({
815
+ messages: [welcomeMessage]
816
+ });
817
+ }
818
+ } catch (error) {
819
+ console.error("Error recreating Dialogflow session after handoff:", error);
820
+ this.setState({
821
+ isLoading: false,
822
+ error: error.message || "Failed to initialize chat"
823
+ });
824
+ const fallbackMessage = {
825
+ id: `fallback-${Date.now()}`,
826
+ text: this.config.fallbackWelcomeMessage || "Hello! How can I help you today?",
827
+ sender: "bot",
828
+ timestamp: /* @__PURE__ */ new Date()
829
+ };
830
+ this.setState({
831
+ messages: [fallbackMessage]
832
+ });
833
+ }
834
+ }
835
+ }, 2e3);
836
+ }
837
+ /**
838
+ * Load message history
839
+ */
840
+ async loadMessageHistory(preserveExisting = false) {
841
+ if (!this.chatService || !this.chatId || !this.supportSessionId) {
842
+ return;
843
+ }
844
+ try {
845
+ if (this.chatId && this.supportSessionId) {
846
+ const history = await this.chatService.loadMessageHistory(this.chatId, this.supportSessionId);
847
+ const historyMessages = history.map((msg) => ({
848
+ id: msg.id || `history-${Date.now()}-${Math.random()}`,
849
+ text: msg.content,
850
+ sender: msg.sender_type === "agent" ? "agent" : "user",
851
+ timestamp: new Date(msg.timestamp)
852
+ }));
853
+ if (preserveExisting) {
854
+ const existingIds = new Set(this.state.messages.map((m) => m.id));
855
+ const newMessages = historyMessages.filter((m) => !existingIds.has(m.id));
856
+ const combined = [...this.state.messages, ...newMessages].sort(
857
+ (a, b) => a.timestamp.getTime() - b.timestamp.getTime()
858
+ );
859
+ this.setState({
860
+ messages: combined
861
+ });
862
+ } else {
863
+ this.setState({
864
+ messages: historyMessages
865
+ });
866
+ }
867
+ }
868
+ } catch (error) {
869
+ console.error("Error loading message history:", error);
870
+ if (this.config.debug) {
871
+ const errorMessage = {
872
+ id: `error-${Date.now()}`,
873
+ text: `Failed to load chat history: ${error.message}`,
874
+ sender: "bot",
875
+ timestamp: /* @__PURE__ */ new Date()
876
+ };
877
+ this.setState({
878
+ messages: [...this.state.messages, errorMessage]
879
+ });
880
+ }
881
+ }
882
+ }
883
+ /**
884
+ * Get additional state for UI (not in WidgetState but needed by components)
885
+ */
886
+ getAdditionalState() {
887
+ return {
888
+ wsConnected: this.wsConnected,
889
+ agentTyping: this.agentTyping,
890
+ currentAgent: this.currentAgent,
891
+ isConnectingToAgent: this.isConnectingToAgent,
892
+ agentAccepted: this.agentAccepted,
893
+ chatResolved: this.chatResolved
894
+ };
895
+ }
896
+ /**
897
+ * Cleanup
898
+ */
899
+ destroy() {
900
+ if (this.typingTimeout) {
901
+ clearTimeout(this.typingTimeout);
902
+ }
903
+ if (this.agentTypingTimeout) {
904
+ clearTimeout(this.agentTypingTimeout);
905
+ }
906
+ if (this.chatService) {
907
+ this.chatService.disconnectWebSocket();
908
+ }
909
+ this.listeners.clear();
910
+ }
911
+ }
912
+ export {
913
+ WidgetStateManager
914
+ };
915
+ //# sourceMappingURL=stateManager.esm.js.map