@om_patel_26/chat-widget 1.0.1

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