@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.
- package/README.md +276 -0
- package/dist/_virtual/_plugin-vue_export-helper.cjs.js +2 -0
- package/dist/_virtual/_plugin-vue_export-helper.cjs.js.map +1 -0
- package/dist/_virtual/_plugin-vue_export-helper.esm.js +11 -0
- package/dist/_virtual/_plugin-vue_export-helper.esm.js.map +1 -0
- package/dist/adapters/vue/index.d.ts +7 -0
- package/dist/adapters/vue/index.d.ts.map +1 -0
- package/dist/adapters/vue/useChatMode.d.ts +21 -0
- package/dist/adapters/vue/useChatMode.d.ts.map +1 -0
- package/dist/components/ChatWidget.d.ts +43 -0
- package/dist/components/ChatWidget.d.ts.map +1 -0
- package/dist/components/ChatWidget.vue.cjs.js +2 -0
- package/dist/components/ChatWidget.vue.cjs.js.map +1 -0
- package/dist/components/ChatWidget.vue.cjs2.js +2 -0
- package/dist/components/ChatWidget.vue.cjs2.js.map +1 -0
- package/dist/components/ChatWidget.vue.esm.js +8 -0
- package/dist/components/ChatWidget.vue.esm.js.map +1 -0
- package/dist/components/ChatWidget.vue.esm2.js +331 -0
- package/dist/components/ChatWidget.vue.esm2.js.map +1 -0
- package/dist/composables/useChatWidget.cjs.js +2 -0
- package/dist/composables/useChatWidget.cjs.js.map +1 -0
- package/dist/composables/useChatWidget.d.ts +34 -0
- package/dist/composables/useChatWidget.d.ts.map +1 -0
- package/dist/composables/useChatWidget.esm.js +72 -0
- package/dist/composables/useChatWidget.esm.js.map +1 -0
- package/dist/core/stateManager.cjs.js +2 -0
- package/dist/core/stateManager.cjs.js.map +1 -0
- package/dist/core/stateManager.d.ts +136 -0
- package/dist/core/stateManager.d.ts.map +1 -0
- package/dist/core/stateManager.esm.js +907 -0
- package/dist/core/stateManager.esm.js.map +1 -0
- package/dist/core/types.d.ts +66 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/entry/next.d.ts +9 -0
- package/dist/entry/next.d.ts.map +1 -0
- package/dist/entry/nuxt.d.ts +10 -0
- package/dist/entry/nuxt.d.ts.map +1 -0
- package/dist/entry/react.d.ts +10 -0
- package/dist/entry/react.d.ts.map +1 -0
- package/dist/entry/vanilla.d.ts +33 -0
- package/dist/entry/vanilla.d.ts.map +1 -0
- package/dist/entry/vite.d.ts +11 -0
- package/dist/entry/vite.d.ts.map +1 -0
- package/dist/entry/vue.d.ts +11 -0
- package/dist/entry/vue.d.ts.map +1 -0
- package/dist/hooks/useChatMode.d.ts +17 -0
- package/dist/hooks/useChatMode.d.ts.map +1 -0
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +25 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jws/compact/sign.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/jws/compact/sign.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jws/compact/sign.esm.js +21 -0
- package/dist/node_modules/jose/dist/browser/jws/compact/sign.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jws/flattened/sign.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/jws/flattened/sign.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jws/flattened/sign.esm.js +84 -0
- package/dist/node_modules/jose/dist/browser/jws/flattened/sign.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jwt/produce.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/jwt/produce.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jwt/produce.esm.js +72 -0
- package/dist/node_modules/jose/dist/browser/jwt/produce.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jwt/sign.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/jwt/sign.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/jwt/sign.esm.js +22 -0
- package/dist/node_modules/jose/dist/browser/jwt/sign.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/key/import.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/key/import.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/key/import.esm.js +11 -0
- package/dist/node_modules/jose/dist/browser/key/import.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/buffer_utils.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/buffer_utils.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/buffer_utils.esm.js +18 -0
- package/dist/node_modules/jose/dist/browser/lib/buffer_utils.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/check_key_type.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/check_key_type.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/check_key_type.esm.js +77 -0
- package/dist/node_modules/jose/dist/browser/lib/check_key_type.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/crypto_key.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/crypto_key.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/crypto_key.esm.js +101 -0
- package/dist/node_modules/jose/dist/browser/lib/crypto_key.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/epoch.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/epoch.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/epoch.esm.js +5 -0
- package/dist/node_modules/jose/dist/browser/lib/epoch.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.esm.js +32 -0
- package/dist/node_modules/jose/dist/browser/lib/invalid_key_input.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/is_disjoint.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/is_disjoint.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/is_disjoint.esm.js +25 -0
- package/dist/node_modules/jose/dist/browser/lib/is_disjoint.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/is_jwk.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/is_jwk.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/is_jwk.esm.js +20 -0
- package/dist/node_modules/jose/dist/browser/lib/is_jwk.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/is_object.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/is_object.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/is_object.esm.js +20 -0
- package/dist/node_modules/jose/dist/browser/lib/is_object.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/secs.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/secs.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/secs.esm.js +59 -0
- package/dist/node_modules/jose/dist/browser/lib/secs.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/validate_crit.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/lib/validate_crit.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/lib/validate_crit.esm.js +34 -0
- package/dist/node_modules/jose/dist/browser/lib/validate_crit.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/asn1.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/asn1.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/asn1.esm.js +103 -0
- package/dist/node_modules/jose/dist/browser/runtime/asn1.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/base64url.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/base64url.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/base64url.esm.js +43 -0
- package/dist/node_modules/jose/dist/browser/runtime/base64url.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/check_key_length.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/check_key_length.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/check_key_length.esm.js +12 -0
- package/dist/node_modules/jose/dist/browser/runtime/check_key_length.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.esm.js +25 -0
- package/dist/node_modules/jose/dist/browser/runtime/get_sign_verify_key.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/is_key_like.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/is_key_like.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/is_key_like.esm.js +13 -0
- package/dist/node_modules/jose/dist/browser/runtime/is_key_like.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.esm.js +107 -0
- package/dist/node_modules/jose/dist/browser/runtime/jwk_to_key.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/normalize_key.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/normalize_key.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/normalize_key.esm.js +71 -0
- package/dist/node_modules/jose/dist/browser/runtime/normalize_key.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/sign.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/sign.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/sign.esm.js +14 -0
- package/dist/node_modules/jose/dist/browser/runtime/sign.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.esm.js +32 -0
- package/dist/node_modules/jose/dist/browser/runtime/subtle_dsa.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/webcrypto.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/runtime/webcrypto.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/runtime/webcrypto.esm.js +7 -0
- package/dist/node_modules/jose/dist/browser/runtime/webcrypto.esm.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/util/errors.cjs.js +2 -0
- package/dist/node_modules/jose/dist/browser/util/errors.cjs.js.map +1 -0
- package/dist/node_modules/jose/dist/browser/util/errors.esm.js +131 -0
- package/dist/node_modules/jose/dist/browser/util/errors.esm.js.map +1 -0
- package/dist/nuxt.cjs.js +2 -0
- package/dist/nuxt.cjs.js.map +1 -0
- package/dist/nuxt.esm.js +8 -0
- package/dist/nuxt.esm.js.map +1 -0
- package/dist/services/chatService.cjs.js +2 -0
- package/dist/services/chatService.cjs.js.map +1 -0
- package/dist/services/chatService.d.ts +144 -0
- package/dist/services/chatService.d.ts.map +1 -0
- package/dist/services/chatService.esm.js +482 -0
- package/dist/services/chatService.esm.js.map +1 -0
- package/dist/services/dialogflowClient.cjs.js +2 -0
- package/dist/services/dialogflowClient.cjs.js.map +1 -0
- package/dist/services/dialogflowClient.d.ts +36 -0
- package/dist/services/dialogflowClient.d.ts.map +1 -0
- package/dist/services/dialogflowClient.esm.js +282 -0
- package/dist/services/dialogflowClient.esm.js.map +1 -0
- package/dist/services/sessionManager.cjs.js +2 -0
- package/dist/services/sessionManager.cjs.js.map +1 -0
- package/dist/services/sessionManager.d.ts +13 -0
- package/dist/services/sessionManager.d.ts.map +1 -0
- package/dist/services/sessionManager.esm.js +48 -0
- package/dist/services/sessionManager.esm.js.map +1 -0
- package/dist/styles.css +0 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/dialogflowHandler.d.ts +31 -0
- package/dist/utils/dialogflowHandler.d.ts.map +1 -0
- package/dist/utils/frameworkDetector.d.ts +17 -0
- package/dist/utils/frameworkDetector.d.ts.map +1 -0
- package/dist/utils/sanitize.cjs.js +2 -0
- package/dist/utils/sanitize.cjs.js.map +1 -0
- package/dist/utils/sanitize.d.ts +25 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.esm.js +57 -0
- package/dist/utils/sanitize.esm.js.map +1 -0
- package/dist/utils/ssr.cjs.js +2 -0
- package/dist/utils/ssr.cjs.js.map +1 -0
- package/dist/utils/ssr.d.ts +35 -0
- package/dist/utils/ssr.d.ts.map +1 -0
- package/dist/utils/ssr.esm.js +48 -0
- package/dist/utils/ssr.esm.js.map +1 -0
- package/dist/vue.cjs.js +2 -0
- package/dist/vue.cjs.js.map +1 -0
- package/dist/vue.esm.js +10 -0
- package/dist/vue.esm.js.map +1 -0
- package/package.json +145 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { defineComponent, ref, computed, watch, nextTick, onMounted, openBlock, createElementBlock, unref, createElementVNode, toDisplayString, withModifiers, createCommentVNode, createTextVNode, Fragment, renderList, normalizeClass } from "vue";
|
|
2
|
+
import { useChatWidget } from "../composables/useChatWidget.esm.js";
|
|
3
|
+
import { safeLinkifyText } from "../utils/sanitize.esm.js";
|
|
4
|
+
const _hoisted_1 = { class: "blockspark-chat-widget" };
|
|
5
|
+
const _hoisted_2 = { class: "blockspark-welcome-header" };
|
|
6
|
+
const _hoisted_3 = { class: "blockspark-welcome-title" };
|
|
7
|
+
const _hoisted_4 = { class: "blockspark-welcome-message" };
|
|
8
|
+
const _hoisted_5 = { class: "blockspark-welcome-cta" };
|
|
9
|
+
const _hoisted_6 = {
|
|
10
|
+
key: 2,
|
|
11
|
+
class: "blockspark-chat-window"
|
|
12
|
+
};
|
|
13
|
+
const _hoisted_7 = { class: "blockspark-chat-header" };
|
|
14
|
+
const _hoisted_8 = { class: "blockspark-chat-header-content" };
|
|
15
|
+
const _hoisted_9 = { class: "blockspark-chat-title" };
|
|
16
|
+
const _hoisted_10 = { class: "blockspark-chat-subtitle" };
|
|
17
|
+
const _hoisted_11 = {
|
|
18
|
+
key: 0,
|
|
19
|
+
class: "blockspark-mode-indicator"
|
|
20
|
+
};
|
|
21
|
+
const _hoisted_12 = {
|
|
22
|
+
key: 0,
|
|
23
|
+
class: "blockspark-mode-badge"
|
|
24
|
+
};
|
|
25
|
+
const _hoisted_13 = {
|
|
26
|
+
key: 1,
|
|
27
|
+
class: "blockspark-agent-info"
|
|
28
|
+
};
|
|
29
|
+
const _hoisted_14 = { class: "blockspark-agent-name" };
|
|
30
|
+
const _hoisted_15 = {
|
|
31
|
+
key: 2,
|
|
32
|
+
class: "blockspark-mode-badge"
|
|
33
|
+
};
|
|
34
|
+
const _hoisted_16 = {
|
|
35
|
+
key: 0,
|
|
36
|
+
class: "blockspark-chat-empty"
|
|
37
|
+
};
|
|
38
|
+
const _hoisted_17 = { class: "blockspark-message-content" };
|
|
39
|
+
const _hoisted_18 = ["innerHTML"];
|
|
40
|
+
const _hoisted_19 = {
|
|
41
|
+
key: 0,
|
|
42
|
+
class: "blockspark-chips-container"
|
|
43
|
+
};
|
|
44
|
+
const _hoisted_20 = {
|
|
45
|
+
key: 0,
|
|
46
|
+
class: "blockspark-chips-group"
|
|
47
|
+
};
|
|
48
|
+
const _hoisted_21 = ["onClick"];
|
|
49
|
+
const _hoisted_22 = {
|
|
50
|
+
key: 0,
|
|
51
|
+
class: "blockspark-chips-group"
|
|
52
|
+
};
|
|
53
|
+
const _hoisted_23 = ["onClick"];
|
|
54
|
+
const _hoisted_24 = { class: "blockspark-message-time" };
|
|
55
|
+
const _hoisted_25 = {
|
|
56
|
+
key: 1,
|
|
57
|
+
class: "blockspark-message blockspark-message-bot"
|
|
58
|
+
};
|
|
59
|
+
const _hoisted_26 = {
|
|
60
|
+
key: 2,
|
|
61
|
+
class: "blockspark-agent-typing-indicator"
|
|
62
|
+
};
|
|
63
|
+
const _hoisted_27 = ["value", "placeholder", "disabled"];
|
|
64
|
+
const _hoisted_28 = ["disabled"];
|
|
65
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
66
|
+
__name: "ChatWidget",
|
|
67
|
+
props: {
|
|
68
|
+
dfProjectId: {},
|
|
69
|
+
dfLocation: {},
|
|
70
|
+
dfAgentId: {},
|
|
71
|
+
serviceAccountKey: {},
|
|
72
|
+
accessToken: {},
|
|
73
|
+
languageCode: {},
|
|
74
|
+
backendBaseUrl: {},
|
|
75
|
+
backendWsUrl: {},
|
|
76
|
+
title: { default: "💬 BlockSpark AI Assistant" },
|
|
77
|
+
subtitle: { default: "We're here to help" },
|
|
78
|
+
welcomeTitle: { default: "👋 Welcome to BlockSpark" },
|
|
79
|
+
welcomeMessage: { default: "My name is BlockSpark AI Assistant and I'll guide you." },
|
|
80
|
+
welcomeCta: { default: "💬 Click here to start chatting!" },
|
|
81
|
+
showWelcomePopup: { type: Boolean, default: true },
|
|
82
|
+
welcomePopupDelay: { default: 1500 },
|
|
83
|
+
fallbackWelcomeMessage: { default: "Hello! I'm BlockSpark AI Assistant. How can I help you today?" },
|
|
84
|
+
inputPlaceholder: { default: "Type your message..." },
|
|
85
|
+
emptyStateMessage: { default: "Hi! I'm BlockSpark AI Assistant. How can I help you today?" },
|
|
86
|
+
debug: { type: Boolean, default: false }
|
|
87
|
+
},
|
|
88
|
+
setup(__props) {
|
|
89
|
+
const props = __props;
|
|
90
|
+
const {
|
|
91
|
+
state,
|
|
92
|
+
isOpen,
|
|
93
|
+
messages,
|
|
94
|
+
isLoading,
|
|
95
|
+
error,
|
|
96
|
+
chatMode,
|
|
97
|
+
wsConnected,
|
|
98
|
+
agentTyping,
|
|
99
|
+
currentAgent,
|
|
100
|
+
openChat,
|
|
101
|
+
closeChat,
|
|
102
|
+
sendMessage,
|
|
103
|
+
toggleChat,
|
|
104
|
+
setInputValue,
|
|
105
|
+
clearError,
|
|
106
|
+
manager
|
|
107
|
+
} = useChatWidget(props);
|
|
108
|
+
const messagesEndRef = ref(null);
|
|
109
|
+
const messagesContainer = ref(null);
|
|
110
|
+
const config = computed(() => props);
|
|
111
|
+
watch(
|
|
112
|
+
() => messages.value.length,
|
|
113
|
+
() => {
|
|
114
|
+
nextTick(() => {
|
|
115
|
+
messagesEndRef.value?.scrollIntoView({ behavior: "smooth" });
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
const handleOpenChat = async () => {
|
|
120
|
+
await openChat();
|
|
121
|
+
};
|
|
122
|
+
const handleCloseChat = () => {
|
|
123
|
+
closeChat();
|
|
124
|
+
};
|
|
125
|
+
const handleCloseWelcomePopup = () => {
|
|
126
|
+
manager.closeWelcomePopup();
|
|
127
|
+
};
|
|
128
|
+
const handleInput = (event) => {
|
|
129
|
+
const target = event.target;
|
|
130
|
+
setInputValue(target.value);
|
|
131
|
+
};
|
|
132
|
+
const handleSubmit = async (event) => {
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
if (state.value.inputValue.trim()) {
|
|
135
|
+
await sendMessage(state.value.inputValue);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const handleChipClick = async (chipText, payload) => {
|
|
139
|
+
const messageToSend = chipText || payload || "";
|
|
140
|
+
await sendMessage(messageToSend);
|
|
141
|
+
};
|
|
142
|
+
const formatTime = (date) => {
|
|
143
|
+
return date.toLocaleTimeString([], {
|
|
144
|
+
hour: "2-digit",
|
|
145
|
+
minute: "2-digit"
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
onMounted(() => {
|
|
149
|
+
if (config.value.showWelcomePopup && typeof window !== "undefined") {
|
|
150
|
+
manager.initializeWelcomePopup();
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
return (_ctx, _cache) => {
|
|
154
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
155
|
+
unref(state).showWelcomePopup && !unref(state).isOpen ? (openBlock(), createElementBlock("div", {
|
|
156
|
+
key: 0,
|
|
157
|
+
class: "blockspark-welcome-popup",
|
|
158
|
+
onClick: handleOpenChat
|
|
159
|
+
}, [
|
|
160
|
+
createElementVNode("div", _hoisted_2, [
|
|
161
|
+
createElementVNode("div", _hoisted_3, toDisplayString(config.value.welcomeTitle), 1),
|
|
162
|
+
createElementVNode("button", {
|
|
163
|
+
class: "blockspark-close-popup",
|
|
164
|
+
onClick: withModifiers(handleCloseWelcomePopup, ["stop"]),
|
|
165
|
+
"aria-label": "Close welcome popup"
|
|
166
|
+
}, " × ")
|
|
167
|
+
]),
|
|
168
|
+
createElementVNode("div", _hoisted_4, toDisplayString(config.value.welcomeMessage), 1),
|
|
169
|
+
createElementVNode("div", _hoisted_5, toDisplayString(config.value.welcomeCta), 1)
|
|
170
|
+
])) : createCommentVNode("", true),
|
|
171
|
+
!unref(state).isOpen ? (openBlock(), createElementBlock("button", {
|
|
172
|
+
key: 1,
|
|
173
|
+
class: "blockspark-chat-toggle-btn",
|
|
174
|
+
onClick: handleOpenChat,
|
|
175
|
+
"aria-label": "Open chat"
|
|
176
|
+
}, [..._cache[0] || (_cache[0] = [
|
|
177
|
+
createElementVNode("svg", {
|
|
178
|
+
width: "24",
|
|
179
|
+
height: "24",
|
|
180
|
+
viewBox: "0 0 24 24",
|
|
181
|
+
fill: "none",
|
|
182
|
+
stroke: "currentColor",
|
|
183
|
+
"stroke-width": "2",
|
|
184
|
+
"stroke-linecap": "round",
|
|
185
|
+
"stroke-linejoin": "round"
|
|
186
|
+
}, [
|
|
187
|
+
createElementVNode("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
|
|
188
|
+
], -1)
|
|
189
|
+
])])) : createCommentVNode("", true),
|
|
190
|
+
unref(state).isOpen ? (openBlock(), createElementBlock("div", _hoisted_6, [
|
|
191
|
+
createElementVNode("div", _hoisted_7, [
|
|
192
|
+
createElementVNode("div", _hoisted_8, [
|
|
193
|
+
createElementVNode("div", _hoisted_9, toDisplayString(config.value.title), 1),
|
|
194
|
+
createElementVNode("div", _hoisted_10, [
|
|
195
|
+
createTextVNode(toDisplayString(config.value.subtitle) + " ", 1),
|
|
196
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("span", _hoisted_11, " • " + toDisplayString(unref(wsConnected) ? "🟢 Connected" : "🟡 Connecting..."), 1)) : createCommentVNode("", true)
|
|
197
|
+
]),
|
|
198
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div", _hoisted_12, " Human Support Mode ")) : createCommentVNode("", true),
|
|
199
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div", _hoisted_13, [
|
|
200
|
+
_cache[1] || (_cache[1] = createElementVNode("span", { class: "blockspark-agent-label" }, "Agent:", -1)),
|
|
201
|
+
createElementVNode("span", _hoisted_14, toDisplayString(unref(currentAgent).name), 1)
|
|
202
|
+
])) : createCommentVNode("", true),
|
|
203
|
+
unref(state).chatMode === "ai" ? (openBlock(), createElementBlock("div", _hoisted_15, " Bot Mode ")) : createCommentVNode("", true)
|
|
204
|
+
]),
|
|
205
|
+
createElementVNode("button", {
|
|
206
|
+
class: "blockspark-chat-close-btn",
|
|
207
|
+
onClick: handleCloseChat,
|
|
208
|
+
"aria-label": "Close chat"
|
|
209
|
+
}, " × ")
|
|
210
|
+
]),
|
|
211
|
+
createElementVNode("div", {
|
|
212
|
+
class: "blockspark-chat-messages",
|
|
213
|
+
ref_key: "messagesContainer",
|
|
214
|
+
ref: messagesContainer
|
|
215
|
+
}, [
|
|
216
|
+
unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_16, [
|
|
217
|
+
_cache[2] || (_cache[2] = createElementVNode("div", { class: "blockspark-chat-empty-icon" }, "👋", -1)),
|
|
218
|
+
createElementVNode("p", null, toDisplayString(config.value.emptyStateMessage), 1)
|
|
219
|
+
])) : createCommentVNode("", true),
|
|
220
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(state).messages, (message) => {
|
|
221
|
+
return openBlock(), createElementBlock("div", {
|
|
222
|
+
key: message.id,
|
|
223
|
+
class: normalizeClass(["blockspark-message", `blockspark-message-${message.sender}`])
|
|
224
|
+
}, [
|
|
225
|
+
createElementVNode("div", _hoisted_17, [
|
|
226
|
+
createElementVNode("span", {
|
|
227
|
+
innerHTML: unref(safeLinkifyText)(message.text)
|
|
228
|
+
}, null, 8, _hoisted_18)
|
|
229
|
+
]),
|
|
230
|
+
message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_19, [
|
|
231
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(message.richContent, (contentGroup, groupIndex) => {
|
|
232
|
+
return openBlock(), createElementBlock(Fragment, { key: groupIndex }, [
|
|
233
|
+
!Array.isArray(contentGroup) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
234
|
+
contentGroup.type === "chips" && contentGroup.options ? (openBlock(), createElementBlock("div", _hoisted_20, [
|
|
235
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(contentGroup.options, (chip, chipIndex) => {
|
|
236
|
+
return openBlock(), createElementBlock("button", {
|
|
237
|
+
key: chipIndex,
|
|
238
|
+
class: "blockspark-chip-button",
|
|
239
|
+
type: "button",
|
|
240
|
+
onClick: ($event) => handleChipClick(chip.text, chip.payload)
|
|
241
|
+
}, toDisplayString(chip.text), 9, _hoisted_21);
|
|
242
|
+
}), 128))
|
|
243
|
+
])) : createCommentVNode("", true)
|
|
244
|
+
], 64)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(contentGroup, (content, contentIndex) => {
|
|
245
|
+
return openBlock(), createElementBlock(Fragment, {
|
|
246
|
+
key: `${groupIndex}-${contentIndex}`
|
|
247
|
+
}, [
|
|
248
|
+
content.type === "chips" && content.options ? (openBlock(), createElementBlock("div", _hoisted_22, [
|
|
249
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(content.options, (chip, chipIndex) => {
|
|
250
|
+
return openBlock(), createElementBlock("button", {
|
|
251
|
+
key: chipIndex,
|
|
252
|
+
class: "blockspark-chip-button",
|
|
253
|
+
type: "button",
|
|
254
|
+
onClick: ($event) => handleChipClick(chip.text, chip.payload)
|
|
255
|
+
}, toDisplayString(chip.text), 9, _hoisted_23);
|
|
256
|
+
}), 128))
|
|
257
|
+
])) : createCommentVNode("", true)
|
|
258
|
+
], 64);
|
|
259
|
+
}), 128))
|
|
260
|
+
], 64);
|
|
261
|
+
}), 128))
|
|
262
|
+
])) : createCommentVNode("", true),
|
|
263
|
+
createElementVNode("div", _hoisted_24, toDisplayString(formatTime(message.timestamp)), 1)
|
|
264
|
+
], 2);
|
|
265
|
+
}), 128)),
|
|
266
|
+
unref(state).isLoading ? (openBlock(), createElementBlock("div", _hoisted_25, [..._cache[3] || (_cache[3] = [
|
|
267
|
+
createElementVNode("div", { class: "blockspark-typing-indicator" }, [
|
|
268
|
+
createElementVNode("span"),
|
|
269
|
+
createElementVNode("span"),
|
|
270
|
+
createElementVNode("span")
|
|
271
|
+
], -1)
|
|
272
|
+
])])) : createCommentVNode("", true),
|
|
273
|
+
unref(state).chatMode === "human" && unref(agentTyping) ? (openBlock(), createElementBlock("div", _hoisted_26, [..._cache[4] || (_cache[4] = [
|
|
274
|
+
createElementVNode("span", { class: "blockspark-typing-dots" }, [
|
|
275
|
+
createElementVNode("span"),
|
|
276
|
+
createElementVNode("span"),
|
|
277
|
+
createElementVNode("span")
|
|
278
|
+
], -1),
|
|
279
|
+
createElementVNode("span", { class: "blockspark-typing-text" }, "Agent is typing...", -1)
|
|
280
|
+
])])) : createCommentVNode("", true),
|
|
281
|
+
createElementVNode("div", {
|
|
282
|
+
ref_key: "messagesEndRef",
|
|
283
|
+
ref: messagesEndRef
|
|
284
|
+
}, null, 512)
|
|
285
|
+
], 512),
|
|
286
|
+
createElementVNode("form", {
|
|
287
|
+
class: "blockspark-chat-input-form",
|
|
288
|
+
onSubmit: withModifiers(handleSubmit, ["prevent"])
|
|
289
|
+
}, [
|
|
290
|
+
createElementVNode("input", {
|
|
291
|
+
type: "text",
|
|
292
|
+
class: "blockspark-chat-input",
|
|
293
|
+
value: unref(state).inputValue,
|
|
294
|
+
onInput: handleInput,
|
|
295
|
+
placeholder: config.value.inputPlaceholder,
|
|
296
|
+
disabled: unref(state).isLoading
|
|
297
|
+
}, null, 40, _hoisted_27),
|
|
298
|
+
createElementVNode("button", {
|
|
299
|
+
type: "submit",
|
|
300
|
+
class: "blockspark-chat-send-btn",
|
|
301
|
+
disabled: !unref(state).inputValue.trim() || unref(state).isLoading
|
|
302
|
+
}, [..._cache[5] || (_cache[5] = [
|
|
303
|
+
createElementVNode("svg", {
|
|
304
|
+
width: "20",
|
|
305
|
+
height: "20",
|
|
306
|
+
viewBox: "0 0 24 24",
|
|
307
|
+
fill: "none",
|
|
308
|
+
stroke: "currentColor",
|
|
309
|
+
"stroke-width": "2",
|
|
310
|
+
"stroke-linecap": "round",
|
|
311
|
+
"stroke-linejoin": "round"
|
|
312
|
+
}, [
|
|
313
|
+
createElementVNode("line", {
|
|
314
|
+
x1: "22",
|
|
315
|
+
y1: "2",
|
|
316
|
+
x2: "11",
|
|
317
|
+
y2: "13"
|
|
318
|
+
}),
|
|
319
|
+
createElementVNode("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
|
|
320
|
+
], -1)
|
|
321
|
+
])], 8, _hoisted_28)
|
|
322
|
+
], 32)
|
|
323
|
+
])) : createCommentVNode("", true)
|
|
324
|
+
]);
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
export {
|
|
329
|
+
_sfc_main as default
|
|
330
|
+
};
|
|
331
|
+
//# sourceMappingURL=ChatWidget.vue.esm2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWidget.vue.esm2.js","sources":["../../src/components/ChatWidget.vue"],"sourcesContent":["<template>\n <div class=\"blockspark-chat-widget\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"blockspark-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"blockspark-welcome-header\">\n <div class=\"blockspark-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"blockspark-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"blockspark-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"blockspark-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"blockspark-chat-toggle-btn\"\n @click=\"handleOpenChat\"\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n\n <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"blockspark-chat-window\">\n <div class=\"blockspark-chat-header\">\n <div class=\"blockspark-chat-header-content\">\n <div class=\"blockspark-chat-title\">{{ config.title }}</div>\n <div class=\"blockspark-chat-subtitle\">\n {{ config.subtitle }}\n <span v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"blockspark-agent-info\">\n <span class=\"blockspark-agent-label\">Agent:</span>\n <span class=\"blockspark-agent-name\">{{ currentAgent.name }}</span>\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"blockspark-mode-badge\">\n Bot Mode\n </div>\n </div>\n <button\n class=\"blockspark-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"blockspark-chat-messages\" ref=\"messagesContainer\">\n <!-- Empty State -->\n <div v-if=\"state.messages.length === 0\" class=\"blockspark-chat-empty\">\n <div class=\"blockspark-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"['blockspark-message', `blockspark-message-${message.sender}`]\"\n >\n <div class=\"blockspark-message-content\">\n <!-- Safe HTML rendering with sanitization -->\n <span v-html=\"safeLinkifyText(message.text)\"></span>\n </div>\n\n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"blockspark-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"blockspark-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"blockspark-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"blockspark-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"blockspark-message blockspark-message-bot\">\n <div class=\"blockspark-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"blockspark-agent-typing-indicator\">\n <span class=\"blockspark-typing-dots\">\n <span></span>\n <span></span>\n <span></span>\n </span>\n <span class=\"blockspark-typing-text\">Agent is typing...</span>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"blockspark-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n type=\"text\"\n class=\"blockspark-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading\"\n />\n <button\n type=\"submit\"\n class=\"blockspark-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.isLoading\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { safeLinkifyText } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\n title: '💬 BlockSpark AI Assistant',\n subtitle: \"We're here to help\",\n welcomeTitle: '👋 Welcome to BlockSpark',\n welcomeMessage: \"My name is BlockSpark AI Assistant and I'll guide you.\",\n welcomeCta: '💬 Click here to start chatting!',\n showWelcomePopup: true,\n welcomePopupDelay: 1500,\n fallbackWelcomeMessage: \"Hello! I'm BlockSpark AI Assistant. How can I help you today?\",\n inputPlaceholder: 'Type your message...',\n emptyStateMessage: \"Hi! I'm BlockSpark AI Assistant. How can I help you today?\",\n debug: false,\n});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_createElementVNode","_toDisplayString","_Fragment","_renderList","_normalizeClass"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),t=require("../core/stateManager.cjs.js");exports.useChatWidget=function(a){const n=new t.WidgetStateManager(a),r=e.ref(n.getState()),s=e.ref(!1),o=e.ref(!1),u=e.ref({name:"Agent"}),c=n.subscribe(e=>{r.value={...e};const t=n.getAdditionalState();s.value=t.wsConnected,o.value=t.agentTyping,u.value=t.currentAgent}),g=e.computed(()=>r.value.isOpen),d=e.computed(()=>r.value.messages),i=e.computed(()=>r.value.isLoading),l=e.computed(()=>r.value.error),p=e.computed(()=>r.value.chatMode);return e.onUnmounted(()=>{c(),n.destroy()}),e.watch(()=>a,e=>{n.updateConfig(e)},{deep:!0}),{state:r,isOpen:g,messages:d,isLoading:i,error:l,chatMode:p,wsConnected:s,agentTyping:o,currentAgent:u,openChat:async()=>{await n.openChat()},closeChat:()=>{n.closeChat()},sendMessage:async e=>{await n.sendMessage(e)},toggleChat:async()=>{await n.toggleChat()},setInputValue:e=>{n.setInputValue(e)},clearError:()=>{n.clearError()},manager:n}};
|
|
2
|
+
//# sourceMappingURL=useChatWidget.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatWidget.cjs.js","sources":["../../src/composables/useChatWidget.ts"],"sourcesContent":["/**\n * useChatWidget Composable\n * Headless mode for Vue 3 - use logic without UI\n */\n\nimport { ref, computed, onUnmounted, watch, readonly, type Ref } from 'vue';\nimport { WidgetStateManager } from '../core/stateManager';\nimport type { WidgetConfig, WidgetState, ChatMessage } from '../core/types';\n\nexport interface UseChatWidgetReturn {\n // State\n state: Readonly<Ref<WidgetState>>;\n isOpen: Readonly<Ref<boolean>>;\n messages: Readonly<Ref<ChatMessage[]>>;\n isLoading: Readonly<Ref<boolean>>;\n error: Readonly<Ref<string | null>>;\n chatMode: Readonly<Ref<'ai' | 'human'>>;\n\n // Additional state\n wsConnected: Readonly<Ref<boolean>>;\n agentTyping: Readonly<Ref<boolean>>;\n currentAgent: Readonly<Ref<{ name: string; id?: string }>>;\n\n // Actions\n openChat: () => Promise<void>;\n closeChat: () => void;\n sendMessage: (text: string) => Promise<void>;\n toggleChat: () => Promise<void>;\n setInputValue: (value: string) => void;\n clearError: () => void;\n\n // Manager instance (for advanced usage)\n manager: WidgetStateManager;\n}\n\n/**\n * Headless chat widget composable\n * Use this for custom UI implementations\n */\nexport function useChatWidget(config: WidgetConfig): UseChatWidgetReturn {\n // Create state manager\n const manager = new WidgetStateManager(config);\n\n // Reactive state\n const state = ref<WidgetState>(manager.getState());\n const wsConnected = ref(false);\n const agentTyping = ref(false);\n const currentAgent = ref<{ name: string; id?: string }>({ name: 'Agent' });\n\n // Subscribe to state changes\n const unsubscribe = manager.subscribe((newState) => {\n state.value = { ...newState };\n \n // Update additional state\n const additional = manager.getAdditionalState();\n wsConnected.value = additional.wsConnected;\n agentTyping.value = additional.agentTyping;\n currentAgent.value = additional.currentAgent;\n });\n\n // Computed properties\n const isOpen = computed(() => state.value.isOpen);\n const messages = computed(() => state.value.messages);\n const isLoading = computed(() => state.value.isLoading);\n const error = computed(() => state.value.error);\n const chatMode = computed(() => state.value.chatMode);\n\n // Actions\n const openChat = async () => {\n await manager.openChat();\n };\n\n const closeChat = () => {\n manager.closeChat();\n };\n\n const sendMessage = async (text: string) => {\n await manager.sendMessage(text);\n };\n\n const toggleChat = async () => {\n await manager.toggleChat();\n };\n\n const setInputValue = (value: string) => {\n manager.setInputValue(value);\n };\n\n const clearError = () => {\n manager.clearError();\n };\n\n // Cleanup on unmount\n onUnmounted(() => {\n unsubscribe();\n manager.destroy();\n });\n\n // Watch config changes\n watch(\n () => config,\n (newConfig) => {\n manager.updateConfig(newConfig);\n },\n { deep: true }\n );\n\n return {\n state: state as Readonly<Ref<WidgetState>>,\n isOpen: isOpen as Readonly<Ref<boolean>>,\n messages: messages as Readonly<Ref<ChatMessage[]>>,\n isLoading: isLoading as Readonly<Ref<boolean>>,\n error: error as Readonly<Ref<string | null>>,\n chatMode: chatMode as Readonly<Ref<'ai' | 'human'>>,\n wsConnected: wsConnected as Readonly<Ref<boolean>>,\n agentTyping: agentTyping as Readonly<Ref<boolean>>,\n currentAgent: currentAgent as Readonly<Ref<{ name: string; id?: string }>>,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n };\n}\n"],"names":["config","manager","WidgetStateManager","state","ref","getState","wsConnected","agentTyping","currentAgent","name","unsubscribe","subscribe","newState","value","additional","getAdditionalState","isOpen","computed","messages","isLoading","error","chatMode","onUnmounted","destroy","watch","newConfig","updateConfig","deep","openChat","async","closeChat","sendMessage","text","toggleChat","setInputValue","clearError"],"mappings":"sKAuCO,SAAuBA,GAE5B,MAAMC,EAAU,IAAIC,EAAAA,mBAAmBF,GAGjCG,EAAQC,EAAAA,IAAiBH,EAAQI,YACjCC,EAAcF,EAAAA,KAAI,GAClBG,EAAcH,EAAAA,KAAI,GAClBI,EAAeJ,EAAAA,IAAmC,CAAEK,KAAM,UAG1DC,EAAcT,EAAQU,UAAWC,IACrCT,EAAMU,MAAQ,IAAKD,GAGnB,MAAME,EAAab,EAAQc,qBAC3BT,EAAYO,MAAQC,EAAWR,YAC/BC,EAAYM,MAAQC,EAAWP,YAC/BC,EAAaK,MAAQC,EAAWN,eAI5BQ,EAASC,EAAAA,SAAS,IAAMd,EAAMU,MAAMG,QACpCE,EAAWD,EAAAA,SAAS,IAAMd,EAAMU,MAAMK,UACtCC,EAAYF,EAAAA,SAAS,IAAMd,EAAMU,MAAMM,WACvCC,EAAQH,EAAAA,SAAS,IAAMd,EAAMU,MAAMO,OACnCC,EAAWJ,EAAAA,SAAS,IAAMd,EAAMU,MAAMQ,UA0C5C,OAdAC,EAAAA,YAAY,KACVZ,IACAT,EAAQsB,YAIVC,EAAAA,MACE,IAAMxB,EACLyB,IACCxB,EAAQyB,aAAaD,IAEvB,CAAEE,MAAM,IAGH,CACLxB,QACAa,SACAE,WACAC,YACAC,QACAC,WACAf,cACAC,cACAC,eACAoB,SAjDeC,gBACT5B,EAAQ2B,YAiDdE,UA9CgB,KAChB7B,EAAQ6B,aA8CRC,YA3CkBF,MAAOG,UACnB/B,EAAQ8B,YAAYC,IA2C1BC,WAxCiBJ,gBACX5B,EAAQgC,cAwCdC,cArCqBrB,IACrBZ,EAAQiC,cAAcrB,IAqCtBsB,WAlCiB,KACjBlC,EAAQkC,cAkCRlC,UAEJ"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useChatWidget Composable
|
|
3
|
+
* Headless mode for Vue 3 - use logic without UI
|
|
4
|
+
*/
|
|
5
|
+
import { type Ref } from 'vue';
|
|
6
|
+
import { WidgetStateManager } from '../core/stateManager';
|
|
7
|
+
import type { WidgetConfig, WidgetState, ChatMessage } from '../core/types';
|
|
8
|
+
export interface UseChatWidgetReturn {
|
|
9
|
+
state: Readonly<Ref<WidgetState>>;
|
|
10
|
+
isOpen: Readonly<Ref<boolean>>;
|
|
11
|
+
messages: Readonly<Ref<ChatMessage[]>>;
|
|
12
|
+
isLoading: Readonly<Ref<boolean>>;
|
|
13
|
+
error: Readonly<Ref<string | null>>;
|
|
14
|
+
chatMode: Readonly<Ref<'ai' | 'human'>>;
|
|
15
|
+
wsConnected: Readonly<Ref<boolean>>;
|
|
16
|
+
agentTyping: Readonly<Ref<boolean>>;
|
|
17
|
+
currentAgent: Readonly<Ref<{
|
|
18
|
+
name: string;
|
|
19
|
+
id?: string;
|
|
20
|
+
}>>;
|
|
21
|
+
openChat: () => Promise<void>;
|
|
22
|
+
closeChat: () => void;
|
|
23
|
+
sendMessage: (text: string) => Promise<void>;
|
|
24
|
+
toggleChat: () => Promise<void>;
|
|
25
|
+
setInputValue: (value: string) => void;
|
|
26
|
+
clearError: () => void;
|
|
27
|
+
manager: WidgetStateManager;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Headless chat widget composable
|
|
31
|
+
* Use this for custom UI implementations
|
|
32
|
+
*/
|
|
33
|
+
export declare function useChatWidget(config: WidgetConfig): UseChatWidgetReturn;
|
|
34
|
+
//# sourceMappingURL=useChatWidget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatWidget.d.ts","sourceRoot":"","sources":["../../src/composables/useChatWidget.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA+C,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAElC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IAClC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/B,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACvC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAClC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACpC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;IAGxC,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACpC,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACpC,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAG3D,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,UAAU,EAAE,MAAM,IAAI,CAAC;IAGvB,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,mBAAmB,CAsFvE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ref, computed, onUnmounted, watch } from "vue";
|
|
2
|
+
import { WidgetStateManager } from "../core/stateManager.esm.js";
|
|
3
|
+
function useChatWidget(config) {
|
|
4
|
+
const manager = new WidgetStateManager(config);
|
|
5
|
+
const state = ref(manager.getState());
|
|
6
|
+
const wsConnected = ref(false);
|
|
7
|
+
const agentTyping = ref(false);
|
|
8
|
+
const currentAgent = ref({ name: "Agent" });
|
|
9
|
+
const unsubscribe = manager.subscribe((newState) => {
|
|
10
|
+
state.value = { ...newState };
|
|
11
|
+
const additional = manager.getAdditionalState();
|
|
12
|
+
wsConnected.value = additional.wsConnected;
|
|
13
|
+
agentTyping.value = additional.agentTyping;
|
|
14
|
+
currentAgent.value = additional.currentAgent;
|
|
15
|
+
});
|
|
16
|
+
const isOpen = computed(() => state.value.isOpen);
|
|
17
|
+
const messages = computed(() => state.value.messages);
|
|
18
|
+
const isLoading = computed(() => state.value.isLoading);
|
|
19
|
+
const error = computed(() => state.value.error);
|
|
20
|
+
const chatMode = computed(() => state.value.chatMode);
|
|
21
|
+
const openChat = async () => {
|
|
22
|
+
await manager.openChat();
|
|
23
|
+
};
|
|
24
|
+
const closeChat = () => {
|
|
25
|
+
manager.closeChat();
|
|
26
|
+
};
|
|
27
|
+
const sendMessage = async (text) => {
|
|
28
|
+
await manager.sendMessage(text);
|
|
29
|
+
};
|
|
30
|
+
const toggleChat = async () => {
|
|
31
|
+
await manager.toggleChat();
|
|
32
|
+
};
|
|
33
|
+
const setInputValue = (value) => {
|
|
34
|
+
manager.setInputValue(value);
|
|
35
|
+
};
|
|
36
|
+
const clearError = () => {
|
|
37
|
+
manager.clearError();
|
|
38
|
+
};
|
|
39
|
+
onUnmounted(() => {
|
|
40
|
+
unsubscribe();
|
|
41
|
+
manager.destroy();
|
|
42
|
+
});
|
|
43
|
+
watch(
|
|
44
|
+
() => config,
|
|
45
|
+
(newConfig) => {
|
|
46
|
+
manager.updateConfig(newConfig);
|
|
47
|
+
},
|
|
48
|
+
{ deep: true }
|
|
49
|
+
);
|
|
50
|
+
return {
|
|
51
|
+
state,
|
|
52
|
+
isOpen,
|
|
53
|
+
messages,
|
|
54
|
+
isLoading,
|
|
55
|
+
error,
|
|
56
|
+
chatMode,
|
|
57
|
+
wsConnected,
|
|
58
|
+
agentTyping,
|
|
59
|
+
currentAgent,
|
|
60
|
+
openChat,
|
|
61
|
+
closeChat,
|
|
62
|
+
sendMessage,
|
|
63
|
+
toggleChat,
|
|
64
|
+
setInputValue,
|
|
65
|
+
clearError,
|
|
66
|
+
manager
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
useChatWidget
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=useChatWidget.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatWidget.esm.js","sources":["../../src/composables/useChatWidget.ts"],"sourcesContent":["/**\n * useChatWidget Composable\n * Headless mode for Vue 3 - use logic without UI\n */\n\nimport { ref, computed, onUnmounted, watch, readonly, type Ref } from 'vue';\nimport { WidgetStateManager } from '../core/stateManager';\nimport type { WidgetConfig, WidgetState, ChatMessage } from '../core/types';\n\nexport interface UseChatWidgetReturn {\n // State\n state: Readonly<Ref<WidgetState>>;\n isOpen: Readonly<Ref<boolean>>;\n messages: Readonly<Ref<ChatMessage[]>>;\n isLoading: Readonly<Ref<boolean>>;\n error: Readonly<Ref<string | null>>;\n chatMode: Readonly<Ref<'ai' | 'human'>>;\n\n // Additional state\n wsConnected: Readonly<Ref<boolean>>;\n agentTyping: Readonly<Ref<boolean>>;\n currentAgent: Readonly<Ref<{ name: string; id?: string }>>;\n\n // Actions\n openChat: () => Promise<void>;\n closeChat: () => void;\n sendMessage: (text: string) => Promise<void>;\n toggleChat: () => Promise<void>;\n setInputValue: (value: string) => void;\n clearError: () => void;\n\n // Manager instance (for advanced usage)\n manager: WidgetStateManager;\n}\n\n/**\n * Headless chat widget composable\n * Use this for custom UI implementations\n */\nexport function useChatWidget(config: WidgetConfig): UseChatWidgetReturn {\n // Create state manager\n const manager = new WidgetStateManager(config);\n\n // Reactive state\n const state = ref<WidgetState>(manager.getState());\n const wsConnected = ref(false);\n const agentTyping = ref(false);\n const currentAgent = ref<{ name: string; id?: string }>({ name: 'Agent' });\n\n // Subscribe to state changes\n const unsubscribe = manager.subscribe((newState) => {\n state.value = { ...newState };\n \n // Update additional state\n const additional = manager.getAdditionalState();\n wsConnected.value = additional.wsConnected;\n agentTyping.value = additional.agentTyping;\n currentAgent.value = additional.currentAgent;\n });\n\n // Computed properties\n const isOpen = computed(() => state.value.isOpen);\n const messages = computed(() => state.value.messages);\n const isLoading = computed(() => state.value.isLoading);\n const error = computed(() => state.value.error);\n const chatMode = computed(() => state.value.chatMode);\n\n // Actions\n const openChat = async () => {\n await manager.openChat();\n };\n\n const closeChat = () => {\n manager.closeChat();\n };\n\n const sendMessage = async (text: string) => {\n await manager.sendMessage(text);\n };\n\n const toggleChat = async () => {\n await manager.toggleChat();\n };\n\n const setInputValue = (value: string) => {\n manager.setInputValue(value);\n };\n\n const clearError = () => {\n manager.clearError();\n };\n\n // Cleanup on unmount\n onUnmounted(() => {\n unsubscribe();\n manager.destroy();\n });\n\n // Watch config changes\n watch(\n () => config,\n (newConfig) => {\n manager.updateConfig(newConfig);\n },\n { deep: true }\n );\n\n return {\n state: state as Readonly<Ref<WidgetState>>,\n isOpen: isOpen as Readonly<Ref<boolean>>,\n messages: messages as Readonly<Ref<ChatMessage[]>>,\n isLoading: isLoading as Readonly<Ref<boolean>>,\n error: error as Readonly<Ref<string | null>>,\n chatMode: chatMode as Readonly<Ref<'ai' | 'human'>>,\n wsConnected: wsConnected as Readonly<Ref<boolean>>,\n agentTyping: agentTyping as Readonly<Ref<boolean>>,\n currentAgent: currentAgent as Readonly<Ref<{ name: string; id?: string }>>,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n };\n}\n"],"names":[],"mappings":";;AAuCO,SAAS,cAAc,QAA2C;AAEvE,QAAM,UAAU,IAAI,mBAAmB,MAAM;AAG7C,QAAM,QAAQ,IAAiB,QAAQ,SAAA,CAAU;AACjD,QAAM,cAAc,IAAI,KAAK;AAC7B,QAAM,cAAc,IAAI,KAAK;AAC7B,QAAM,eAAe,IAAmC,EAAE,MAAM,SAAS;AAGzE,QAAM,cAAc,QAAQ,UAAU,CAAC,aAAa;AAClD,UAAM,QAAQ,EAAE,GAAG,SAAA;AAGnB,UAAM,aAAa,QAAQ,mBAAA;AAC3B,gBAAY,QAAQ,WAAW;AAC/B,gBAAY,QAAQ,WAAW;AAC/B,iBAAa,QAAQ,WAAW;AAAA,EAClC,CAAC;AAGD,QAAM,SAAS,SAAS,MAAM,MAAM,MAAM,MAAM;AAChD,QAAM,WAAW,SAAS,MAAM,MAAM,MAAM,QAAQ;AACpD,QAAM,YAAY,SAAS,MAAM,MAAM,MAAM,SAAS;AACtD,QAAM,QAAQ,SAAS,MAAM,MAAM,MAAM,KAAK;AAC9C,QAAM,WAAW,SAAS,MAAM,MAAM,MAAM,QAAQ;AAGpD,QAAM,WAAW,YAAY;AAC3B,UAAM,QAAQ,SAAA;AAAA,EAChB;AAEA,QAAM,YAAY,MAAM;AACtB,YAAQ,UAAA;AAAA,EACV;AAEA,QAAM,cAAc,OAAO,SAAiB;AAC1C,UAAM,QAAQ,YAAY,IAAI;AAAA,EAChC;AAEA,QAAM,aAAa,YAAY;AAC7B,UAAM,QAAQ,WAAA;AAAA,EAChB;AAEA,QAAM,gBAAgB,CAAC,UAAkB;AACvC,YAAQ,cAAc,KAAK;AAAA,EAC7B;AAEA,QAAM,aAAa,MAAM;AACvB,YAAQ,WAAA;AAAA,EACV;AAGA,cAAY,MAAM;AAChB,gBAAA;AACA,YAAQ,QAAA;AAAA,EACV,CAAC;AAGD;AAAA,IACE,MAAM;AAAA,IACN,CAAC,cAAc;AACb,cAAQ,aAAa,SAAS;AAAA,IAChC;AAAA,IACA,EAAE,MAAM,KAAA;AAAA,EAAK;AAGf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../services/dialogflowClient.cjs.js"),t=require("../services/chatService.cjs.js"),s=require("../utils/ssr.cjs.js");exports.WidgetStateManager=class{constructor(e){this.listeners=new Set,this.chatMode="ai",this.chatId=null,this.supportSessionId=null,this.chatService=null,this.collectingUserInfo=!1,this.userInfoStep=null,this.collectedUserName="",this.collectedUserEmail="",this.collectedUserMobile="",this.wsConnected=!1,this.agentTyping=!1,this.currentAgent={name:"Agent"},this.isConnectingToAgent=!1,this.agentAccepted=!1,this.chatResolved=!1,this.historyLoaded=null,this.typingTimeout=null,this.agentTypingTimeout=null,this.config=e,this.state={isOpen:!1,showWelcomePopup:!1,messages:[],inputValue:"",isLoading:!1,error:null,sessionId:null,chatMode:"ai"},this.chatService=t.createChatService({baseUrl:this.config.backendBaseUrl||"http://localhost:8012",wsUrl:this.config.backendWsUrl||"ws://localhost:8012",debug:this.config.debug||!1});const i=s.safeLocalStorage(),a=i.getItem("blockspark_chat_mode");a&&(this.chatMode="HUMAN"===a?"human":"ai",this.state.chatMode=this.chatMode),this.chatId=i.getItem("blockspark_chat_id"),this.supportSessionId=i.getItem("blockspark_session_id")}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getState(){return{...this.state}}setState(e){this.state={...this.state,...e},this.listeners.forEach(e=>e(this.getState()))}updateConfig(e){this.config={...this.config,...e}}async openChat(){if(this.setState({isOpen:!0}),this.state.showWelcomePopup&&this.setState({showWelcomePopup:!1}),"ai"===this.state.chatMode&&!this.state.sessionId&&this.config.dfProjectId&&this.config.dfAgentId)try{this.setState({isLoading:!0});const t={dfProjectId:this.config.dfProjectId,dfLocation:this.config.dfLocation||"us-central1",dfAgentId:this.config.dfAgentId,serviceAccountKey:this.config.serviceAccountKey,accessToken:this.config.accessToken,languageCode:this.config.languageCode||"en"},s=await e.createDialogflowSession(t);if(this.setState({sessionId:s.session_id,isLoading:!1}),s.message){const e={id:`welcome-${Date.now()}`,text:s.message,sender:"bot",timestamp:new Date,richContent:s.richContent};this.setState({messages:[e]})}}catch(t){this.setState({isLoading:!1,error:t.message||"Failed to initialize chat"});const e={id:`fallback-${Date.now()}`,text:this.config.fallbackWelcomeMessage||"Hello! How can I help you today?",sender:"bot",timestamp:new Date};this.setState({messages:[e]})}}closeChat(){this.setState({isOpen:!1})}closeWelcomePopup(){this.setState({showWelcomePopup:!1})}toggleChat(){const e=!this.state.isOpen;this.setState({isOpen:e}),e&&this.state.showWelcomePopup&&this.setState({showWelcomePopup:!1})}setInputValue(e){this.setState({inputValue:e})}clearError(){this.setState({error:null})}async sendMessage(e,s=!1){if(e.trim()&&!this.state.isLoading){if(this.collectingUserInfo){const t={id:`user-${Date.now()}`,text:e.trim(),sender:"user",timestamp:new Date};return this.setState({messages:[...this.state.messages,t],inputValue:"",isLoading:!1,error:null}),void(await this.handleUserInfoCollection(e))}if(s)this.setState({inputValue:"",isLoading:!0,error:null});else{const t={id:`user-${Date.now()}`,text:e.trim(),sender:"user",timestamp:new Date};this.setState({messages:[...this.state.messages,t],inputValue:"",isLoading:!0,error:null})}try{"human"===this.state.chatMode?await this.sendHumanMessage(e):await this.sendAIMessage(e)}catch(i){if(i instanceof t.ChatResolvedError||"ChatResolvedError"===i?.name||"chat_resolved"===i?.message)return void this.enterResolvedState(this.chatId);const e={id:`error-${Date.now()}`,text:this.config.debug?`Error: ${i.message||"Failed to send message"}`:i.message?.includes("CORS")||i.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.",sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,e],error:i.message||"Failed to send message",isLoading:!1})}}}async sendAIMessage(t){if(!this.config.dfProjectId||!this.config.dfAgentId)throw new Error("Dialogflow configuration is missing");const s={dfProjectId:this.config.dfProjectId,dfLocation:this.config.dfLocation||"us-central1",dfAgentId:this.config.dfAgentId,serviceAccountKey:this.config.serviceAccountKey,accessToken:this.config.accessToken,languageCode:this.config.languageCode||"en"};if(!this.state.sessionId){const t=await e.createDialogflowSession(s);this.setState({sessionId:t.session_id})}this.config.debug;const i=await e.sendDialogflowMessage(t,this.state.sessionId,s);if(this.config.debug,!0===i.handoff){const e={id:`bot-${Date.now()}`,text:i.response||this.config.fallbackWelcomeMessage||"No response",sender:"bot",timestamp:new Date,richContent:i.richContent};return this.setState({messages:[...this.state.messages,e],isLoading:!1}),void this.startUserInfoCollection()}const a={id:`bot-${Date.now()}`,text:i.response||this.config.fallbackWelcomeMessage||"No response",sender:"bot",timestamp:new Date,richContent:i.richContent};this.setState({messages:[...this.state.messages,a],isLoading:!1})}async sendHumanMessage(e){if(!this.chatId||!this.supportSessionId){const e={id:`error-${Date.now()}`,text:"Chat session not initialized. Please try again.",sender:"bot",timestamp:new Date};return void this.setState({messages:[...this.state.messages,e],isLoading:!1})}if(!this.chatService)throw new Error("Chat service not initialized");this.chatService.sendTypingIndicator("typing_stop"),this.typingTimeout&&(clearTimeout(this.typingTimeout),this.typingTimeout=null);try{this.chatService.sendMessageViaWebSocket(e.trim())||await this.chatService.sendMessageToAgent(this.chatId,this.supportSessionId,e.trim()),this.setState({isLoading:!1})}catch(i){if(i instanceof t.ChatResolvedError||"ChatResolvedError"===i?.name||"chat_resolved"===i?.message)return void this.enterResolvedState(this.chatId);if(!(i.message?.includes("Chat not found")||i.message?.includes("unauthorized")||i.message?.includes("401")||i.message?.includes("404")))throw i;{this.config.debug,this.chatId=null,this.supportSessionId=null;const i=s.safeLocalStorage();i.removeItem("blockspark_chat_id"),i.removeItem("blockspark_session_id");try{const t=await this.chatService.startSupportChat(this.state.sessionId||null,null,null,null);this.chatId=t.chat_id,this.supportSessionId=t.session_id;const i=s.safeLocalStorage();return i.setItem("blockspark_chat_id",this.chatId),i.setItem("blockspark_session_id",this.supportSessionId),this.chatId&&this.supportSessionId&&await this.chatService.sendMessageToAgent(this.chatId,this.supportSessionId,e.trim()),void this.setState({isLoading:!1})}catch(a){if(a instanceof t.ChatResolvedError||"chat_resolved"===a?.message)return void this.enterResolvedState(this.chatId);throw a}}}}switchToHumanMode(){this.chatMode="human",this.setState({chatMode:"human"}),s.safeLocalStorage().setItem("blockspark_chat_mode","HUMAN")}switchToBotMode(){this.chatMode="ai",this.setState({chatMode:"ai"}),s.safeLocalStorage().setItem("blockspark_chat_mode","BOT")}initializeWelcomePopup(){if(!1!==this.config.showWelcomePopup){const e=this.config.welcomePopupDelay||1500;setTimeout(()=>{this.state.isOpen||this.setState({showWelcomePopup:!0})},e)}}startUserInfoCollection(){this.collectingUserInfo=!0,this.userInfoStep="name",this.collectedUserName="",this.collectedUserEmail="",this.collectedUserMobile="";const e={id:`prompt-${Date.now()}`,text:"To connect you with a human agent, I'll need some information. Please provide your name:",sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,e]})}async handleUserInfoCollection(e){if("name"===this.userInfoStep){const t=e.trim();this.collectedUserName=t,this.userInfoStep="email";const s={id:`prompt-${Date.now()}`,text:"Thank you! Now please provide your email address:",sender:"bot",timestamp:new Date};return void this.setState({messages:[...this.state.messages,s],inputValue:""})}if("email"===this.userInfoStep){const t=e.trim();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)){const e={id:`prompt-${Date.now()}`,text:"Please provide a valid email address:",sender:"bot",timestamp:new Date};return void this.setState({messages:[...this.state.messages,e],inputValue:""})}this.collectedUserEmail=t,this.userInfoStep="mobile";const s={id:`prompt-${Date.now()}`,text:"Thank you! Now please provide your mobile number:",sender:"bot",timestamp:new Date};return void this.setState({messages:[...this.state.messages,s],inputValue:""})}if("mobile"===this.userInfoStep){const t=e.trim();if(!/^[\+]?[(]?[0-9]{1,4}[)]?[-\s\.]?[(]?[0-9]{1,4}[)]?[-\s\.]?[0-9]{1,9}$/.test(t)||t.length<10){const e={id:`prompt-${Date.now()}`,text:"Please provide a valid mobile number (e.g., +1234567890):",sender:"bot",timestamp:new Date};return void this.setState({messages:[...this.state.messages,e],inputValue:""})}this.collectedUserMobile=t,this.collectingUserInfo=!1,this.userInfoStep=null,await this.handleHandoff(this.collectedUserName,this.collectedUserEmail,t),this.setState({inputValue:""})}}async handleHandoff(e,t,i){if(!this.chatService)throw new Error("Chat service not initialized");try{this.isConnectingToAgent=!0;const n=this.state.sessionId,o=await this.chatService.ensureChatInitialized(this.chatId,this.supportSessionId,n||null,e||null,t||null,i||null);if(!o||!o.chat_id)throw new Error("Failed to initialize chat session");const c=o.chat_id,h=o.session_id;if(c!==this.chatId){this.chatId=c,this.supportSessionId=h;const e=s.safeLocalStorage();e.setItem("blockspark_chat_id",this.chatId),e.setItem("blockspark_session_id",this.supportSessionId),this.config.debug}try{await this.chatService.requestHandoff(c,h,"Customer requested human agent",n||null,e||null,t||null,i||null),this.config.debug}catch(a){if(!(a.message?.includes("Invalid chat_id")||a.message?.includes("Chat not found")||a.message?.includes("unauthorized")||a.message?.includes("400")||a.message?.includes("401")||a.message?.includes("404")||a.message?.includes("expired")))throw a;{this.config.debug,this.chatId=null,this.supportSessionId=null;const a=s.safeLocalStorage();a.removeItem("blockspark_chat_id"),a.removeItem("blockspark_session_id");const o=await this.chatService.startSupportChat(n||null,e||null,t||null,i||null);if(!o||!o.chat_id)throw new Error("Failed to re-initialize chat session");this.chatId=o.chat_id,this.supportSessionId=o.session_id;const c=s.safeLocalStorage();c.setItem("blockspark_chat_id",this.chatId),c.setItem("blockspark_session_id",this.supportSessionId),await this.chatService.requestHandoff(this.chatId,this.supportSessionId,"Customer requested human agent",n||null,e||null,t||null,i||null),this.config.debug}}this.switchToHumanMode(),this.chatResolved=!1,this.agentAccepted=!1;const r={id:`connecting-${Date.now()}`,text:"Connecting you to a human agent...",sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,r]}),c&&h&&this.chatService.connectWebSocket(c,h,e=>{this.handleWebSocketMessage(e)},e=>{this.wsConnected=e}),this.isConnectingToAgent=!1}catch(n){const e={id:`error-${Date.now()}`,text:this.config.debug?`Handoff error: ${n.message}`:"Failed to connect to agent. Please try again.",sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,e]}),this.isConnectingToAgent=!1}}handleWebSocketMessage(e){switch(e.type){case"message":if(e.content&&("agent"===e.sender_type||!e.sender_type)){const t={id:e.id||`agent-${Date.now()}`,text:e.content,sender:"agent",timestamp:new Date(e.timestamp||Date.now())};new Set(this.state.messages.map(e=>e.id)).has(t.id)||this.setState({messages:[...this.state.messages,t]}),this.agentTyping=!1,this.agentTypingTimeout&&(clearTimeout(this.agentTypingTimeout),this.agentTypingTimeout=null)}break;case"typing_start":"agent"===e.sender_type&&(this.agentTyping=!0,this.agentTypingTimeout&&clearTimeout(this.agentTypingTimeout),this.agentTypingTimeout=setTimeout(()=>{this.agentTyping=!1},3e3));break;case"typing_stop":"agent"===e.sender_type&&(this.agentTyping=!1,this.agentTypingTimeout&&(clearTimeout(this.agentTypingTimeout),this.agentTypingTimeout=null));break;case"agent_changed":if(e.to_agent){this.currentAgent={id:e.to_agent_id,name:e.to_agent};const t={id:`system-${Date.now()}`,text:e.from_agent?`Chat has been transferred from ${e.from_agent} to ${e.to_agent}`:`Chat has been transferred to ${e.to_agent}`,sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,t]})}break;case"agent_accepted":this.agentAccepted=!0,this.isConnectingToAgent=!1;const t={id:e.id||`agent-accepted-${Date.now()}`,text:"You can chat now, the agent has accepted your request.",sender:"bot",timestamp:e.timestamp?new Date(e.timestamp):new Date};new Set(this.state.messages.map(e=>e.id)).has(t.id)||this.setState({messages:[...this.state.messages,t]}),e.to_agent&&(this.currentAgent={name:e.to_agent,id:e.to_agent_id});break;case"chat_resolved":case"chat_ended":this.enterResolvedState(e.chat_id||null);break;case"chat_info":"active"===e.status?(this.isConnectingToAgent=!1,this.agentAccepted=!0):"resolved"!==e.status&&"ended"!==e.status||this.enterResolvedState(e.chat_id||null),e.agent_id&&(this.currentAgent={...this.currentAgent,id:e.agent_id});break;case"error":const s={id:`error-${Date.now()}`,text:e.error||"An error occurred. Please try again.",sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,s]})}}enterResolvedState(t){this.chatResolved=!0,this.isConnectingToAgent=!1,this.agentAccepted=!1,this.agentTyping=!1,this.agentTypingTimeout&&(clearTimeout(this.agentTypingTimeout),this.agentTypingTimeout=null),this.chatService&&this.chatService.disconnectWebSocket(),this.chatId=null,this.supportSessionId=null;const i=s.safeLocalStorage();i.removeItem("blockspark_chat_id"),i.removeItem("blockspark_session_id");const a={id:`resolved-${Date.now()}`,text:"Thank you for contacting us!",sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,a]}),setTimeout(async()=>{if(this.switchToBotMode(),this.chatResolved=!1,this.setState({messages:[],sessionId:null}),this.collectingUserInfo=!1,this.userInfoStep=null,this.collectedUserName="",this.collectedUserEmail="",this.collectedUserMobile="",this.config.dfProjectId&&this.config.dfAgentId&&this.state.isOpen)try{this.setState({isLoading:!0});const t={dfProjectId:this.config.dfProjectId,dfLocation:this.config.dfLocation||"us-central1",dfAgentId:this.config.dfAgentId,serviceAccountKey:this.config.serviceAccountKey,accessToken:this.config.accessToken,languageCode:this.config.languageCode||"en"},s=await e.createDialogflowSession(t);if(this.setState({sessionId:s.session_id,isLoading:!1}),s.message){const e={id:`welcome-${Date.now()}`,text:s.message,sender:"bot",timestamp:new Date,richContent:s.richContent};this.setState({messages:[e]})}}catch(t){this.setState({isLoading:!1,error:t.message||"Failed to initialize chat"});const e={id:`fallback-${Date.now()}`,text:this.config.fallbackWelcomeMessage||"Hello! How can I help you today?",sender:"bot",timestamp:new Date};this.setState({messages:[e]})}},2e3)}async loadMessageHistory(e=!1){if(this.chatService&&this.chatId&&this.supportSessionId)try{if(this.chatId&&this.supportSessionId){const t=(await this.chatService.loadMessageHistory(this.chatId,this.supportSessionId)).map(e=>({id:e.id||`history-${Date.now()}-${Math.random()}`,text:e.content,sender:"agent"===e.sender_type?"agent":"user",timestamp:new Date(e.timestamp)}));if(e){const e=new Set(this.state.messages.map(e=>e.id)),s=t.filter(t=>!e.has(t.id)),i=[...this.state.messages,...s].sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());this.setState({messages:i})}else this.setState({messages:t})}}catch(t){if(this.config.debug){const e={id:`error-${Date.now()}`,text:`Failed to load chat history: ${t.message}`,sender:"bot",timestamp:new Date};this.setState({messages:[...this.state.messages,e]})}}}getAdditionalState(){return{wsConnected:this.wsConnected,agentTyping:this.agentTyping,currentAgent:this.currentAgent,isConnectingToAgent:this.isConnectingToAgent,agentAccepted:this.agentAccepted,chatResolved:this.chatResolved}}destroy(){this.typingTimeout&&clearTimeout(this.typingTimeout),this.agentTypingTimeout&&clearTimeout(this.agentTypingTimeout),this.chatService&&this.chatService.disconnectWebSocket(),this.listeners.clear()}};
|
|
2
|
+
//# sourceMappingURL=stateManager.cjs.js.map
|