@n8n/chat 0.6.0 → 0.6.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 (205) hide show
  1. package/{src/App.vue → App.vue} +2 -2
  2. package/README.md +27 -4
  3. package/__stories__/App.stories.d.ts +16 -0
  4. package/__stories__/App.stories.js +38 -0
  5. package/__stories__/App.stories.mjs +32 -0
  6. package/__tests__/index.spec.d.ts +1 -0
  7. package/__tests__/index.spec.js +146 -0
  8. package/__tests__/index.spec.mjs +172 -0
  9. package/__tests__/setup.js +3 -0
  10. package/__tests__/setup.mjs +1 -0
  11. package/__tests__/utils/create.d.ts +5 -0
  12. package/__tests__/utils/create.js +16 -0
  13. package/__tests__/utils/create.mjs +10 -0
  14. package/__tests__/utils/fetch.d.ts +3 -0
  15. package/__tests__/utils/fetch.js +20 -0
  16. package/__tests__/utils/fetch.mjs +9 -0
  17. package/__tests__/utils/index.js +38 -0
  18. package/__tests__/utils/index.mjs +3 -0
  19. package/__tests__/utils/selectors.d.ts +12 -0
  20. package/__tests__/utils/selectors.js +58 -0
  21. package/__tests__/utils/selectors.mjs +41 -0
  22. package/api/generic.d.ts +6 -0
  23. package/api/generic.js +68 -0
  24. package/api/generic.mjs +54 -0
  25. package/api/index.js +27 -0
  26. package/api/index.mjs +2 -0
  27. package/api/message.d.ts +3 -0
  28. package/api/message.js +33 -0
  29. package/api/message.mjs +30 -0
  30. package/chat.bundle.es.js +10753 -0
  31. package/chat.bundle.umd.js +18 -0
  32. package/chat.es.js +6864 -0
  33. package/chat.umd.js +18 -0
  34. package/components/Button.vue +34 -0
  35. package/{src/components → components}/Chat.vue +19 -15
  36. package/components/ChatWindow.vue +104 -0
  37. package/components/GetStarted.vue +24 -0
  38. package/{src/components → components}/GetStartedFooter.vue +4 -4
  39. package/{src/components → components}/Input.vue +35 -40
  40. package/components/Layout.vue +66 -0
  41. package/components/Message.vue +94 -0
  42. package/components/MessageTyping.vue +101 -0
  43. package/{src/components → components}/MessagesList.vue +8 -8
  44. package/{src/components → components}/PoweredBy.vue +6 -7
  45. package/components/index.js +76 -0
  46. package/components/index.mjs +10 -0
  47. package/composables/index.js +38 -0
  48. package/composables/index.mjs +3 -0
  49. package/composables/useChat.d.ts +1 -0
  50. package/composables/useChat.js +11 -0
  51. package/composables/useChat.mjs +5 -0
  52. package/composables/useI18n.d.ts +4 -0
  53. package/composables/useI18n.js +23 -0
  54. package/composables/useI18n.mjs +12 -0
  55. package/composables/useOptions.d.ts +3 -0
  56. package/composables/useOptions.js +14 -0
  57. package/composables/useOptions.mjs +8 -0
  58. package/constants/defaults.d.ts +3 -0
  59. package/constants/defaults.js +32 -0
  60. package/constants/defaults.mjs +26 -0
  61. package/constants/index.js +38 -0
  62. package/constants/index.mjs +3 -0
  63. package/constants/localStorage.d.ts +2 -0
  64. package/constants/localStorage.js +8 -0
  65. package/{src/constants/localStorage.ts → constants/localStorage.mjs} +1 -1
  66. package/constants/symbols.d.ts +3 -0
  67. package/constants/symbols.js +8 -0
  68. package/constants/symbols.mjs +2 -0
  69. package/css/index.css +31 -0
  70. package/event-buses/chatEventBus.d.ts +1 -0
  71. package/event-buses/chatEventBus.js +8 -0
  72. package/event-buses/chatEventBus.mjs +2 -0
  73. package/event-buses/index.js +16 -0
  74. package/event-buses/index.mjs +1 -0
  75. package/index.d.ts +3 -0
  76. package/index.js +43 -0
  77. package/index.mjs +36 -0
  78. package/main.css +151 -0
  79. package/package.json +41 -5
  80. package/plugins/chat.d.ts +3 -0
  81. package/plugins/chat.js +85 -0
  82. package/plugins/chat.mjs +83 -0
  83. package/plugins/index.js +16 -0
  84. package/plugins/index.mjs +1 -0
  85. package/style.css +1 -0
  86. package/types/App.vue.d.ts +8 -0
  87. package/types/__stories__/App.stories.d.ts +17 -0
  88. package/types/__tests__/index.spec.d.ts +1 -0
  89. package/types/__tests__/setup.d.ts +0 -0
  90. package/types/__tests__/utils/create.d.ts +5 -0
  91. package/types/__tests__/utils/fetch.d.ts +4 -0
  92. package/types/__tests__/utils/index.d.ts +3 -0
  93. package/types/__tests__/utils/selectors.d.ts +12 -0
  94. package/types/api/generic.d.ts +6 -0
  95. package/types/api/index.d.ts +2 -0
  96. package/types/api/message.d.ts +3 -0
  97. package/types/chat.d.ts +11 -0
  98. package/types/chat.js +1 -0
  99. package/types/chat.mjs +0 -0
  100. package/types/components/Button.vue.d.ts +9 -0
  101. package/types/components/Chat.vue.d.ts +2 -0
  102. package/types/components/ChatWindow.vue.d.ts +2 -0
  103. package/types/components/GetStarted.vue.d.ts +2 -0
  104. package/types/components/GetStartedFooter.vue.d.ts +2 -0
  105. package/types/components/Input.vue.d.ts +2 -0
  106. package/types/components/Layout.vue.d.ts +11 -0
  107. package/types/components/Message.vue.d.ts +21 -0
  108. package/types/components/MessageTyping.vue.d.ts +15 -0
  109. package/types/components/MessagesList.vue.d.ts +14 -0
  110. package/types/components/PoweredBy.vue.d.ts +2 -0
  111. package/types/components/index.d.ts +10 -0
  112. package/types/composables/index.d.ts +3 -0
  113. package/types/composables/useChat.d.ts +2 -0
  114. package/types/composables/useI18n.d.ts +4 -0
  115. package/types/composables/useOptions.d.ts +4 -0
  116. package/types/constants/defaults.d.ts +3 -0
  117. package/types/constants/index.d.ts +3 -0
  118. package/types/constants/localStorage.d.ts +2 -0
  119. package/types/constants/symbols.d.ts +4 -0
  120. package/types/event-buses/chatEventBus.d.ts +1 -0
  121. package/types/event-buses/index.d.ts +1 -0
  122. package/types/index.js +49 -0
  123. package/types/index.mjs +4 -0
  124. package/types/messages.d.ts +6 -0
  125. package/types/messages.js +1 -0
  126. package/types/messages.mjs +0 -0
  127. package/types/options.d.ts +25 -0
  128. package/types/options.js +1 -0
  129. package/types/options.mjs +0 -0
  130. package/types/plugins/chat.d.ts +3 -0
  131. package/types/plugins/index.d.ts +1 -0
  132. package/types/types/chat.d.ts +11 -0
  133. package/types/types/index.d.ts +4 -0
  134. package/types/types/messages.d.ts +6 -0
  135. package/types/types/options.d.ts +25 -0
  136. package/types/types/webhook.d.ts +15 -0
  137. package/types/utils/event-bus.d.ts +8 -0
  138. package/types/utils/mount.d.ts +1 -0
  139. package/types/webhook.d.ts +15 -0
  140. package/types/webhook.js +1 -0
  141. package/types/webhook.mjs +0 -0
  142. package/utils/event-bus.d.ts +8 -0
  143. package/utils/event-bus.js +38 -0
  144. package/utils/event-bus.mjs +32 -0
  145. package/utils/index.d.ts +2 -0
  146. package/utils/index.js +27 -0
  147. package/utils/index.mjs +2 -0
  148. package/utils/mount.d.ts +1 -0
  149. package/utils/mount.js +19 -0
  150. package/utils/mount.mjs +13 -0
  151. package/.eslintignore +0 -2
  152. package/.eslintrc.cjs +0 -51
  153. package/.np-config.json +0 -5
  154. package/.storybook/main.ts +0 -27
  155. package/.storybook/preview.scss +0 -4
  156. package/.storybook/preview.ts +0 -16
  157. package/.vscode/extensions.json +0 -3
  158. package/env.d.ts +0 -1
  159. package/index.html +0 -13
  160. package/resources/workflow.json +0 -293
  161. package/scripts/pack.js +0 -11
  162. package/scripts/postbuild.js +0 -16
  163. package/src/__stories__/App.stories.ts +0 -43
  164. package/src/__tests__/index.spec.ts +0 -223
  165. package/src/__tests__/utils/create.ts +0 -16
  166. package/src/__tests__/utils/fetch.ts +0 -18
  167. package/src/__tests__/utils/selectors.ts +0 -53
  168. package/src/api/generic.ts +0 -64
  169. package/src/api/message.ts +0 -31
  170. package/src/components/Button.vue +0 -41
  171. package/src/components/ChatWindow.vue +0 -125
  172. package/src/components/GetStarted.vue +0 -24
  173. package/src/components/Layout.vue +0 -82
  174. package/src/components/Message.vue +0 -97
  175. package/src/components/MessageTyping.vue +0 -109
  176. package/src/composables/useChat.ts +0 -7
  177. package/src/composables/useI18n.ts +0 -16
  178. package/src/composables/useOptions.ts +0 -11
  179. package/src/constants/defaults.ts +0 -25
  180. package/src/constants/symbols.ts +0 -8
  181. package/src/event-buses/chatEventBus.ts +0 -3
  182. package/src/index.ts +0 -42
  183. package/src/main.scss +0 -40
  184. package/src/plugins/chat.ts +0 -101
  185. package/src/types/chat.ts +0 -12
  186. package/src/types/messages.ts +0 -6
  187. package/src/types/options.ts +0 -23
  188. package/src/types/webhook.ts +0 -17
  189. package/src/utils/event-bus.ts +0 -51
  190. package/src/utils/mount.ts +0 -16
  191. package/tsconfig.json +0 -27
  192. package/vite.config.ts +0 -51
  193. package/vitest.config.ts +0 -20
  194. /package/{src/__tests__/setup.ts → __tests__/setup.d.ts} +0 -0
  195. /package/{src/__tests__/utils/index.ts → __tests__/utils/index.d.ts} +0 -0
  196. /package/{src/api/index.ts → api/index.d.ts} +0 -0
  197. /package/{src/components/index.ts → components/index.d.ts} +0 -0
  198. /package/{src/composables/index.ts → composables/index.d.ts} +0 -0
  199. /package/{src/constants/index.ts → constants/index.d.ts} +0 -0
  200. /package/{src/event-buses/index.ts → event-buses/index.d.ts} +0 -0
  201. /package/{public/favicon.ico → favicon.ico} +0 -0
  202. /package/{src/plugins/index.ts → plugins/index.d.ts} +0 -0
  203. /package/{src/shims.d.ts → shims.d.ts} +0 -0
  204. /package/{src/types/index.ts → types/index.d.ts} +0 -0
  205. /package/{src/utils/index.ts → types/utils/index.d.ts} +0 -0
@@ -1,82 +0,0 @@
1
- <script setup lang="ts">
2
- import { onBeforeUnmount, onMounted, ref } from 'vue';
3
- import { chatEventBus } from '@/event-buses';
4
-
5
- const chatBodyRef = ref<HTMLElement | null>(null);
6
-
7
- function scrollToBottom() {
8
- const element = chatBodyRef.value as HTMLElement;
9
- if (element) {
10
- element.scrollTop = element.scrollHeight;
11
- }
12
- }
13
-
14
- onMounted(() => {
15
- chatEventBus.on('scrollToBottom', scrollToBottom);
16
- window.addEventListener('resize', scrollToBottom);
17
- });
18
-
19
- onBeforeUnmount(() => {
20
- chatEventBus.off('scrollToBottom', scrollToBottom);
21
- window.removeEventListener('resize', scrollToBottom);
22
- });
23
- </script>
24
- <template>
25
- <main class="chat-layout">
26
- <div v-if="$slots.header" class="chat-header">
27
- <slot name="header" />
28
- </div>
29
- <div v-if="$slots.default" class="chat-body" ref="chatBodyRef">
30
- <slot />
31
- </div>
32
- <div v-if="$slots.footer" class="chat-footer">
33
- <slot name="footer" />
34
- </div>
35
- </main>
36
- </template>
37
-
38
- <style lang="scss">
39
- .chat-layout {
40
- width: 100%;
41
- height: 100%;
42
- display: flex;
43
- overflow-y: auto;
44
- flex-direction: column;
45
- font-family: var(
46
- --chat--font-family,
47
- (
48
- -apple-system,
49
- BlinkMacSystemFont,
50
- 'Segoe UI',
51
- Roboto,
52
- Oxygen-Sans,
53
- Ubuntu,
54
- Cantarell,
55
- 'Helvetica Neue',
56
- sans-serif
57
- )
58
- );
59
-
60
- .chat-header {
61
- padding: var(--chat--header--padding, var(--chat--spacing));
62
- background: var(--chat--header--background, var(--chat--color-dark));
63
- color: var(--chat--header--color, var(--chat--color-light));
64
- }
65
-
66
- .chat-body {
67
- background: var(--chat--body--background, var(--chat--color-light));
68
- flex: 1;
69
- display: flex;
70
- flex-direction: column;
71
- overflow-y: auto;
72
- position: relative;
73
- min-height: 100px;
74
- }
75
-
76
- .chat-footer {
77
- border-top: 1px solid var(--chat--color-light-shade-100);
78
- background: var(--chat--footer--background, var(--chat--color-light));
79
- color: var(--chat--footer--color, var(--chat--color-dark));
80
- }
81
- }
82
- </style>
@@ -1,97 +0,0 @@
1
- <script lang="ts" setup>
2
- /* eslint-disable @typescript-eslint/naming-convention */
3
- import type { ChatMessage } from '@/types';
4
- import type { PropType } from 'vue';
5
- import { computed, toRefs } from 'vue';
6
- import VueMarkdown from 'vue-markdown-render';
7
- import hljs from 'highlight.js/lib/core';
8
-
9
- const props = defineProps({
10
- message: {
11
- type: Object as PropType<ChatMessage>,
12
- required: true,
13
- },
14
- });
15
-
16
- const { message } = toRefs(props);
17
-
18
- const classes = computed(() => {
19
- return {
20
- 'chat-message-from-user': message.value.sender === 'user',
21
- 'chat-message-from-bot': message.value.sender === 'bot',
22
- };
23
- });
24
-
25
- const markdownOptions = {
26
- highlight(str: string, lang: string) {
27
- if (lang && hljs.getLanguage(lang)) {
28
- try {
29
- return hljs.highlight(str, { language: lang }).value;
30
- } catch {}
31
- }
32
-
33
- return ''; // use external default escaping
34
- },
35
- };
36
- </script>
37
- <template>
38
- <div class="chat-message" :class="classes">
39
- <slot>
40
- <vue-markdown
41
- class="chat-message-markdown"
42
- :source="message.text"
43
- :options="markdownOptions"
44
- />
45
- </slot>
46
- </div>
47
- </template>
48
-
49
- <style lang="scss">
50
- .chat-message {
51
- display: block;
52
- max-width: 80%;
53
- padding: var(--chat--message--padding, var(--chat--spacing));
54
- border-radius: var(--chat--message--border-radius, var(--chat--border-radius));
55
-
56
- + .chat-message {
57
- margin-top: var(--chat--message--margin-bottom, calc(var(--chat--spacing) * 0.5));
58
- }
59
-
60
- &.chat-message-from-bot {
61
- background-color: var(--chat--message--bot--background);
62
- color: var(--chat--message--bot--color);
63
- border-bottom-left-radius: 0;
64
- }
65
-
66
- &.chat-message-from-user {
67
- background-color: var(--chat--message--user--background);
68
- color: var(--chat--message--user--color);
69
- margin-left: auto;
70
- border-bottom-right-radius: 0;
71
- }
72
-
73
- > .chat-message-markdown {
74
- display: block;
75
- box-sizing: border-box;
76
-
77
- > *:first-child {
78
- margin-top: 0;
79
- }
80
-
81
- > *:last-child {
82
- margin-bottom: 0;
83
- }
84
-
85
- pre {
86
- font-family: inherit;
87
- font-size: inherit;
88
- margin: 0;
89
- white-space: pre-wrap;
90
- box-sizing: border-box;
91
- padding: var(--chat--spacing);
92
- background: var(--chat--message--pre--background);
93
- border-radius: var(--chat--border-radius);
94
- }
95
- }
96
- }
97
- </style>
@@ -1,109 +0,0 @@
1
- <script lang="ts" setup>
2
- import type { ChatMessage } from '@/types';
3
- import { Message } from './index';
4
- import type { PropType } from 'vue';
5
- import { computed } from 'vue';
6
-
7
- const props = defineProps({
8
- animation: {
9
- type: String as PropType<'bouncing' | 'scaling'>,
10
- default: 'bouncing',
11
- },
12
- });
13
-
14
- const message: ChatMessage = {
15
- id: 'typing',
16
- text: '',
17
- sender: 'bot',
18
- createdAt: '',
19
- };
20
-
21
- const classes = computed(() => {
22
- return {
23
- // eslint-disable-next-line @typescript-eslint/naming-convention
24
- 'chat-message-typing': true,
25
- [`chat-message-typing-animation-${props.animation}`]: true,
26
- };
27
- });
28
- </script>
29
- <template>
30
- <Message :class="classes" :message="message">
31
- <div class="chat-message-typing-body">
32
- <span class="chat-message-typing-circle"></span>
33
- <span class="chat-message-typing-circle"></span>
34
- <span class="chat-message-typing-circle"></span>
35
- </div>
36
- </Message>
37
- </template>
38
- <style lang="scss">
39
- .chat-message-typing {
40
- max-width: 80px;
41
-
42
- &.chat-message-typing-animation-scaling .chat-message-typing-circle {
43
- animation: chat-message-typing-animation-scaling 800ms ease-in-out infinite;
44
- animation-delay: 3600ms;
45
- }
46
-
47
- &.chat-message-typing-animation-bouncing .chat-message-typing-circle {
48
- animation: chat-message-typing-animation-bouncing 800ms ease-in-out infinite;
49
- animation-delay: 3600ms;
50
- }
51
-
52
- .chat-message-typing-body {
53
- display: flex;
54
- justify-content: center;
55
- align-items: center;
56
- }
57
-
58
- .chat-message-typing-circle {
59
- display: block;
60
- height: 10px;
61
- width: 10px;
62
- border-radius: 50%;
63
- background-color: var(--chat--color-typing);
64
- margin: 3px;
65
-
66
- &:nth-child(1) {
67
- animation-delay: 0ms;
68
- }
69
-
70
- &:nth-child(2) {
71
- animation-delay: 333ms;
72
- }
73
-
74
- &:nth-child(3) {
75
- animation-delay: 666ms;
76
- }
77
- }
78
- }
79
-
80
- @keyframes chat-message-typing-animation-scaling {
81
- 0% {
82
- transform: scale(1);
83
- }
84
- 33% {
85
- transform: scale(1);
86
- }
87
- 50% {
88
- transform: scale(1.4);
89
- }
90
- 100% {
91
- transform: scale(1);
92
- }
93
- }
94
-
95
- @keyframes chat-message-typing-animation-bouncing {
96
- 0% {
97
- transform: translateY(0);
98
- }
99
- 33% {
100
- transform: translateY(0);
101
- }
102
- 50% {
103
- transform: translateY(-10px);
104
- }
105
- 100% {
106
- transform: translateY(0);
107
- }
108
- }
109
- </style>
@@ -1,7 +0,0 @@
1
- import { inject } from 'vue';
2
- import { ChatSymbol } from '@/constants';
3
- import type { Chat } from '@/types';
4
-
5
- export function useChat() {
6
- return inject(ChatSymbol) as Chat;
7
- }
@@ -1,16 +0,0 @@
1
- import { useOptions } from '@/composables/useOptions';
2
-
3
- export function useI18n() {
4
- const { options } = useOptions();
5
- const language = options?.defaultLanguage ?? 'en';
6
-
7
- function t(key: string): string {
8
- return options?.i18n?.[language]?.[key] ?? key;
9
- }
10
-
11
- function te(key: string): boolean {
12
- return !!options?.i18n?.[language]?.[key];
13
- }
14
-
15
- return { t, te };
16
- }
@@ -1,11 +0,0 @@
1
- import { inject } from 'vue';
2
- import { ChatOptionsSymbol } from '@/constants';
3
- import type { ChatOptions } from '@/types';
4
-
5
- export function useOptions() {
6
- const options = inject(ChatOptionsSymbol) as ChatOptions;
7
-
8
- return {
9
- options,
10
- };
11
- }
@@ -1,25 +0,0 @@
1
- import type { ChatOptions } from '@/types';
2
-
3
- export const defaultOptions: ChatOptions = {
4
- webhookUrl: 'http://localhost:5678',
5
- webhookConfig: {
6
- method: 'POST',
7
- headers: {},
8
- },
9
- target: '#n8n-chat',
10
- mode: 'window',
11
- defaultLanguage: 'en',
12
- initialMessages: ['Hi there! 👋', 'My name is Nathan. How can I assist you today?'],
13
- i18n: {
14
- en: {
15
- title: 'Hi there! 👋',
16
- subtitle: "Start a chat. We're here to help you 24/7.",
17
- footer: '',
18
- getStarted: 'New Conversation',
19
- inputPlaceholder: 'Type your question..',
20
- },
21
- },
22
- theme: {},
23
- };
24
-
25
- export const defaultMountingTarget = '#n8n-chat';
@@ -1,8 +0,0 @@
1
- import type { InjectionKey } from 'vue';
2
- import type { Chat, ChatOptions } from '@/types';
3
-
4
- // eslint-disable-next-line @typescript-eslint/naming-convention
5
- export const ChatSymbol = 'Chat' as unknown as InjectionKey<Chat>;
6
-
7
- // eslint-disable-next-line @typescript-eslint/naming-convention
8
- export const ChatOptionsSymbol = 'ChatOptions' as unknown as InjectionKey<ChatOptions>;
@@ -1,3 +0,0 @@
1
- import { createEventBus } from '@/utils';
2
-
3
- export const chatEventBus = createEventBus();
package/src/index.ts DELETED
@@ -1,42 +0,0 @@
1
- import './main.scss';
2
-
3
- import { createApp } from 'vue';
4
- import App from './App.vue';
5
- import type { ChatOptions } from '@/types';
6
- import { defaultMountingTarget, defaultOptions } from '@/constants';
7
- import { createDefaultMountingTarget } from '@/utils';
8
- import { ChatPlugin } from '@/plugins';
9
-
10
- export function createChat(options?: Partial<ChatOptions>) {
11
- const resolvedOptions: ChatOptions = {
12
- ...defaultOptions,
13
- ...options,
14
- webhookConfig: {
15
- ...defaultOptions.webhookConfig,
16
- ...options?.webhookConfig,
17
- },
18
- i18n: {
19
- ...defaultOptions.i18n,
20
- ...options?.i18n,
21
- en: {
22
- ...defaultOptions.i18n?.en,
23
- ...options?.i18n?.en,
24
- },
25
- },
26
- theme: {
27
- ...defaultOptions.theme,
28
- ...options?.theme,
29
- },
30
- };
31
-
32
- const mountingTarget = resolvedOptions.target ?? defaultMountingTarget;
33
- if (typeof mountingTarget === 'string') {
34
- createDefaultMountingTarget(mountingTarget);
35
- }
36
-
37
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
38
- const app = createApp(App);
39
- app.use(ChatPlugin, resolvedOptions);
40
- app.mount(mountingTarget);
41
- return app;
42
- }
package/src/main.scss DELETED
@@ -1,40 +0,0 @@
1
- .n8n-chat {
2
- @import 'highlight.js/styles/github';
3
- }
4
-
5
- :root {
6
- --chat--color-primary: #e74266;
7
- --chat--color-primary-shade-50: #db4061;
8
- --chat--color-primary-shade-100: #cf3c5c;
9
- --chat--color-secondary: #20b69e;
10
- --chat--color-secondary-shade-50: #1ca08a;
11
- --chat--color-white: #ffffff;
12
- --chat--color-light: #f2f4f8;
13
- --chat--color-light-shade-50: #e6e9f1;
14
- --chat--color-light-shade-100: #c2c5cc;
15
- --chat--color-medium: #d2d4d9;
16
- --chat--color-dark: #101330;
17
- --chat--color-disabled: #777980;
18
- --chat--color-typing: #404040;
19
-
20
- --chat--spacing: 1rem;
21
- --chat--border-radius: 0.25rem;
22
- --chat--transition-duration: 0.15s;
23
-
24
- --chat--window--width: 400px;
25
- --chat--window--height: 600px;
26
-
27
- --chat--textarea--height: 50px;
28
-
29
- --chat--message--bot--background: var(--chat--color-white);
30
- --chat--message--bot--color: var(--chat--color-dark);
31
- --chat--message--user--background: var(--chat--color-secondary);
32
- --chat--message--user--color: var(--chat--color-white);
33
- --chat--message--pre--background: rgba(0, 0, 0, 0.05);
34
-
35
- --chat--toggle--background: var(--chat--color-primary);
36
- --chat--toggle--hover--background: var(--chat--color-primary-shade-50);
37
- --chat--toggle--active--background: var(--chat--color-primary-shade-100);
38
- --chat--toggle--color: var(--chat--color-white);
39
- --chat--toggle--size: 64px;
40
- }
@@ -1,101 +0,0 @@
1
- import type { Plugin } from 'vue';
2
- import { computed, nextTick, ref } from 'vue';
3
- import type { ChatMessage, ChatOptions } from '@/types';
4
- import { v4 as uuidv4 } from 'uuid';
5
- import { chatEventBus } from '@/event-buses';
6
- import * as api from '@/api';
7
- import { ChatOptionsSymbol, ChatSymbol, localStorageSessionIdKey } from '@/constants';
8
-
9
- // eslint-disable-next-line @typescript-eslint/naming-convention
10
- export const ChatPlugin: Plugin<ChatOptions> = {
11
- install(app, options) {
12
- app.provide(ChatOptionsSymbol, options);
13
-
14
- const messages = ref<ChatMessage[]>([]);
15
- const currentSessionId = ref<string | null>(null);
16
- const waitingForResponse = ref(false);
17
-
18
- const initialMessages = computed<ChatMessage[]>(() =>
19
- (options.initialMessages ?? []).map((text) => ({
20
- id: uuidv4(),
21
- text,
22
- sender: 'bot',
23
- createdAt: new Date().toISOString(),
24
- })),
25
- );
26
-
27
- async function sendMessage(text: string) {
28
- const sentMessage: ChatMessage = {
29
- id: uuidv4(),
30
- text,
31
- sender: 'user',
32
- createdAt: new Date().toISOString(),
33
- };
34
-
35
- messages.value.push(sentMessage);
36
- waitingForResponse.value = true;
37
-
38
- void nextTick(() => {
39
- chatEventBus.emit('scrollToBottom');
40
- });
41
-
42
- const sendMessageResponse = await api.sendMessage(
43
- text,
44
- currentSessionId.value as string,
45
- options,
46
- );
47
-
48
- const receivedMessage: ChatMessage = {
49
- id: uuidv4(),
50
- text: sendMessageResponse.output,
51
- sender: 'bot',
52
- createdAt: new Date().toISOString(),
53
- };
54
- messages.value.push(receivedMessage);
55
-
56
- waitingForResponse.value = false;
57
-
58
- void nextTick(() => {
59
- chatEventBus.emit('scrollToBottom');
60
- });
61
- }
62
-
63
- async function loadPreviousSession() {
64
- const sessionId = localStorage.getItem(localStorageSessionIdKey) ?? uuidv4();
65
- const previousMessagesResponse = await api.loadPreviousSession(sessionId, options);
66
- const timestamp = new Date().toISOString();
67
-
68
- messages.value = (previousMessagesResponse?.data || []).map((message, index) => ({
69
- id: `${index}`,
70
- text: message.kwargs.content,
71
- sender: message.id.includes('HumanMessage') ? 'user' : 'bot',
72
- createdAt: timestamp,
73
- }));
74
-
75
- if (messages.value.length) {
76
- currentSessionId.value = sessionId;
77
- }
78
-
79
- return sessionId;
80
- }
81
-
82
- async function startNewSession() {
83
- currentSessionId.value = uuidv4();
84
-
85
- localStorage.setItem(localStorageSessionIdKey, currentSessionId.value);
86
- }
87
-
88
- const chatStore = {
89
- initialMessages,
90
- messages,
91
- currentSessionId,
92
- waitingForResponse,
93
- loadPreviousSession,
94
- startNewSession,
95
- sendMessage,
96
- };
97
-
98
- app.provide(ChatSymbol, chatStore);
99
- app.config.globalProperties.$chat = chatStore;
100
- },
101
- };
package/src/types/chat.ts DELETED
@@ -1,12 +0,0 @@
1
- import type { ChatMessage } from '@/types/messages';
2
- import type { Ref } from 'vue';
3
-
4
- export interface Chat {
5
- initialMessages: Ref<ChatMessage[]>;
6
- messages: Ref<ChatMessage[]>;
7
- currentSessionId: Ref<string | null>;
8
- waitingForResponse: Ref<boolean>;
9
- loadPreviousSession: () => Promise<string>;
10
- startNewSession: () => Promise<void>;
11
- sendMessage: (text: string) => Promise<void>;
12
- }
@@ -1,6 +0,0 @@
1
- export interface ChatMessage {
2
- id: string;
3
- text: string;
4
- createdAt: string;
5
- sender: 'user' | 'bot';
6
- }
@@ -1,23 +0,0 @@
1
- export interface ChatOptions {
2
- webhookUrl: string;
3
- webhookConfig?: {
4
- method?: 'GET' | 'POST';
5
- headers?: Record<string, string>;
6
- };
7
- target?: string | Element;
8
- mode?: 'window' | 'fullscreen';
9
- defaultLanguage?: 'en';
10
- initialMessages?: string[];
11
- i18n: Record<
12
- string,
13
- {
14
- title: string;
15
- subtitle: string;
16
- footer: string;
17
- getStarted: string;
18
- inputPlaceholder: string;
19
- [message: string]: string;
20
- }
21
- >;
22
- theme?: {};
23
- }
@@ -1,17 +0,0 @@
1
- export interface LoadPreviousSessionResponseItem {
2
- id: string[];
3
- kwargs: {
4
- content: string;
5
- additional_kwargs: Record<string, unknown>;
6
- };
7
- lc: number;
8
- type: string;
9
- }
10
-
11
- export interface LoadPreviousSessionResponse {
12
- data: LoadPreviousSessionResponseItem[];
13
- }
14
-
15
- export interface SendMessageResponse {
16
- output: string;
17
- }
@@ -1,51 +0,0 @@
1
- // eslint-disable-next-line @typescript-eslint/ban-types
2
- export type CallbackFn = Function;
3
- export type UnregisterFn = () => void;
4
-
5
- export interface EventBus {
6
- on: (eventName: string, fn: CallbackFn) => UnregisterFn;
7
- off: (eventName: string, fn: CallbackFn) => void;
8
- emit: <T = Event>(eventName: string, event?: T) => void;
9
- }
10
-
11
- export function createEventBus(): EventBus {
12
- const handlers = new Map<string, CallbackFn[]>();
13
-
14
- function off(eventName: string, fn: CallbackFn) {
15
- const eventFns = handlers.get(eventName);
16
-
17
- if (eventFns) {
18
- eventFns.splice(eventFns.indexOf(fn) >>> 0, 1);
19
- }
20
- }
21
-
22
- function on(eventName: string, fn: CallbackFn): UnregisterFn {
23
- let eventFns = handlers.get(eventName);
24
-
25
- if (!eventFns) {
26
- eventFns = [fn];
27
- } else {
28
- eventFns.push(fn);
29
- }
30
-
31
- handlers.set(eventName, eventFns);
32
-
33
- return () => off(eventName, fn);
34
- }
35
-
36
- function emit<T = Event>(eventName: string, event?: T) {
37
- const eventFns = handlers.get(eventName);
38
-
39
- if (eventFns) {
40
- eventFns.slice().forEach(async (handler) => {
41
- await handler(event);
42
- });
43
- }
44
- }
45
-
46
- return {
47
- on,
48
- off,
49
- emit,
50
- };
51
- }
@@ -1,16 +0,0 @@
1
- export function createDefaultMountingTarget(mountingTarget: string) {
2
- const mountingTargetNode = document.querySelector(mountingTarget);
3
- if (!mountingTargetNode) {
4
- const generatedMountingTargetNode = document.createElement('div');
5
-
6
- if (mountingTarget.startsWith('#')) {
7
- generatedMountingTargetNode.id = mountingTarget.replace('#', '');
8
- }
9
-
10
- if (mountingTarget.startsWith('.')) {
11
- generatedMountingTargetNode.classList.add(mountingTarget.replace('.', ''));
12
- }
13
-
14
- document.body.appendChild(generatedMountingTargetNode);
15
- }
16
- }