@lingshuai/chat-vue 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +239 -0
- package/dist/index.d.ts +239 -0
- package/dist/index.js +147 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +127 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +53 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
import { Ref } from 'vue';
|
|
3
|
+
import * as _lingshuai_chat_core from '@lingshuai/chat-core';
|
|
4
|
+
import { ChatConfig, Message, Conversation, ChatClient, ChatEventType, ChatEventListener, ChatState } from '@lingshuai/chat-core';
|
|
5
|
+
export { ApiClient, ChatClient, ChatConfig, ChatEventListener, ChatEventMap, ChatEventType, ChatState, Conversation, EventEmitter, Message, MessageRole, MessageStatus, SendMessageRequest, SendMessageResponse, StateListener, StateManager, ThemeConfig, WidgetConfig } from '@lingshuai/chat-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* useChat Composable - 提供完整的聊天功能
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```vue
|
|
12
|
+
* <script setup>
|
|
13
|
+
* import { useChat } from '@lingshuai/chat-vue';
|
|
14
|
+
*
|
|
15
|
+
* const {
|
|
16
|
+
* messages,
|
|
17
|
+
* isSending,
|
|
18
|
+
* input,
|
|
19
|
+
* sendMessage,
|
|
20
|
+
* } = useChat({
|
|
21
|
+
* apiKey: 'your-api-key',
|
|
22
|
+
* appId: 'your-app-id',
|
|
23
|
+
* });
|
|
24
|
+
* </script>
|
|
25
|
+
*
|
|
26
|
+
* <template>
|
|
27
|
+
* <div>
|
|
28
|
+
* <div v-for="msg in messages" :key="msg.id">
|
|
29
|
+
* {{ msg.content }}
|
|
30
|
+
* </div>
|
|
31
|
+
* <input v-model="input" @keydown.enter="sendMessage(input)" />
|
|
32
|
+
* <button @click="sendMessage(input)" :disabled="isSending">发送</button>
|
|
33
|
+
* </div>
|
|
34
|
+
* </template>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function useChat(config: ChatConfig): {
|
|
38
|
+
messages: Ref<{
|
|
39
|
+
id: string;
|
|
40
|
+
conversationId: string;
|
|
41
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
42
|
+
content: string;
|
|
43
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
44
|
+
createdAt: Date;
|
|
45
|
+
metadata?: Record<string, unknown> | undefined;
|
|
46
|
+
}[], Message[] | {
|
|
47
|
+
id: string;
|
|
48
|
+
conversationId: string;
|
|
49
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
50
|
+
content: string;
|
|
51
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
52
|
+
createdAt: Date;
|
|
53
|
+
metadata?: Record<string, unknown> | undefined;
|
|
54
|
+
}[]>;
|
|
55
|
+
conversations: Ref<{
|
|
56
|
+
id: string;
|
|
57
|
+
title?: string | undefined;
|
|
58
|
+
messages: {
|
|
59
|
+
id: string;
|
|
60
|
+
conversationId: string;
|
|
61
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
62
|
+
content: string;
|
|
63
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
64
|
+
createdAt: Date;
|
|
65
|
+
metadata?: Record<string, unknown> | undefined;
|
|
66
|
+
}[];
|
|
67
|
+
createdAt: Date;
|
|
68
|
+
updatedAt: Date;
|
|
69
|
+
}[], Conversation[] | {
|
|
70
|
+
id: string;
|
|
71
|
+
title?: string | undefined;
|
|
72
|
+
messages: {
|
|
73
|
+
id: string;
|
|
74
|
+
conversationId: string;
|
|
75
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
76
|
+
content: string;
|
|
77
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
78
|
+
createdAt: Date;
|
|
79
|
+
metadata?: Record<string, unknown> | undefined;
|
|
80
|
+
}[];
|
|
81
|
+
createdAt: Date;
|
|
82
|
+
updatedAt: Date;
|
|
83
|
+
}[]>;
|
|
84
|
+
currentConversation: Ref<{
|
|
85
|
+
id: string;
|
|
86
|
+
title?: string | undefined;
|
|
87
|
+
messages: {
|
|
88
|
+
id: string;
|
|
89
|
+
conversationId: string;
|
|
90
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
91
|
+
content: string;
|
|
92
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
93
|
+
createdAt: Date;
|
|
94
|
+
metadata?: Record<string, unknown> | undefined;
|
|
95
|
+
}[];
|
|
96
|
+
createdAt: Date;
|
|
97
|
+
updatedAt: Date;
|
|
98
|
+
} | null, Conversation | {
|
|
99
|
+
id: string;
|
|
100
|
+
title?: string | undefined;
|
|
101
|
+
messages: {
|
|
102
|
+
id: string;
|
|
103
|
+
conversationId: string;
|
|
104
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
105
|
+
content: string;
|
|
106
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
107
|
+
createdAt: Date;
|
|
108
|
+
metadata?: Record<string, unknown> | undefined;
|
|
109
|
+
}[];
|
|
110
|
+
createdAt: Date;
|
|
111
|
+
updatedAt: Date;
|
|
112
|
+
} | null>;
|
|
113
|
+
isSending: Ref<boolean, boolean>;
|
|
114
|
+
isLoading: Ref<boolean, boolean>;
|
|
115
|
+
error: Ref<Error | null, Error | null>;
|
|
116
|
+
input: Ref<string, string>;
|
|
117
|
+
sendMessage: (content: string) => Promise<void>;
|
|
118
|
+
abort: () => void;
|
|
119
|
+
newConversation: () => void;
|
|
120
|
+
switchConversation: (conversationId: string) => Promise<void>;
|
|
121
|
+
deleteConversation: (conversationId: string) => Promise<void>;
|
|
122
|
+
getConversations: () => Promise<never[] | Conversation[]>;
|
|
123
|
+
client: vue.ShallowRef<ChatClient | null, ChatClient | null>;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* useChatClient Composable - 创建 ChatClient 实例
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```vue
|
|
130
|
+
* <script setup>
|
|
131
|
+
* import { useChatClient } from '@lingshuai/chat-vue';
|
|
132
|
+
*
|
|
133
|
+
* const client = useChatClient({
|
|
134
|
+
* apiKey: 'your-api-key',
|
|
135
|
+
* appId: 'your-app-id',
|
|
136
|
+
* });
|
|
137
|
+
*
|
|
138
|
+
* client.on('message:received', ({ message }) => {
|
|
139
|
+
* console.log('收到消息:', message.content);
|
|
140
|
+
* });
|
|
141
|
+
* </script>
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare function useChatClient(config: ChatConfig): Ref<ChatClient | null>;
|
|
145
|
+
/**
|
|
146
|
+
* useChatEvent Composable - 监听聊天事件
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```vue
|
|
150
|
+
* <script setup>
|
|
151
|
+
* import { useChatClient, useChatEvent } from '@lingshuai/chat-vue';
|
|
152
|
+
*
|
|
153
|
+
* const client = useChatClient({ apiKey: 'xxx', appId: 'xxx' });
|
|
154
|
+
*
|
|
155
|
+
* useChatEvent(client, 'message:stream:chunk', ({ fullContent }) => {
|
|
156
|
+
* console.log('流式内容:', fullContent);
|
|
157
|
+
* });
|
|
158
|
+
* </script>
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
declare function useChatEvent<T extends ChatEventType>(client: Ref<ChatClient | null>, event: T, listener: ChatEventListener<T>): void;
|
|
162
|
+
/**
|
|
163
|
+
* useChatState Composable - 订阅聊天状态
|
|
164
|
+
*/
|
|
165
|
+
declare function useChatState(client: Ref<ChatClient | null>): Ref<{
|
|
166
|
+
currentConversation: {
|
|
167
|
+
id: string;
|
|
168
|
+
title?: string | undefined;
|
|
169
|
+
messages: {
|
|
170
|
+
id: string;
|
|
171
|
+
conversationId: string;
|
|
172
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
173
|
+
content: string;
|
|
174
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
175
|
+
createdAt: Date;
|
|
176
|
+
metadata?: Record<string, unknown> | undefined;
|
|
177
|
+
}[];
|
|
178
|
+
createdAt: Date;
|
|
179
|
+
updatedAt: Date;
|
|
180
|
+
} | null;
|
|
181
|
+
conversations: {
|
|
182
|
+
id: string;
|
|
183
|
+
title?: string | undefined;
|
|
184
|
+
messages: {
|
|
185
|
+
id: string;
|
|
186
|
+
conversationId: string;
|
|
187
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
188
|
+
content: string;
|
|
189
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
190
|
+
createdAt: Date;
|
|
191
|
+
metadata?: Record<string, unknown> | undefined;
|
|
192
|
+
}[];
|
|
193
|
+
createdAt: Date;
|
|
194
|
+
updatedAt: Date;
|
|
195
|
+
}[];
|
|
196
|
+
isSending: boolean;
|
|
197
|
+
isLoading: boolean;
|
|
198
|
+
isConnected: boolean;
|
|
199
|
+
error: Error | null;
|
|
200
|
+
inputValue: string;
|
|
201
|
+
}, ChatState | {
|
|
202
|
+
currentConversation: {
|
|
203
|
+
id: string;
|
|
204
|
+
title?: string | undefined;
|
|
205
|
+
messages: {
|
|
206
|
+
id: string;
|
|
207
|
+
conversationId: string;
|
|
208
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
209
|
+
content: string;
|
|
210
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
211
|
+
createdAt: Date;
|
|
212
|
+
metadata?: Record<string, unknown> | undefined;
|
|
213
|
+
}[];
|
|
214
|
+
createdAt: Date;
|
|
215
|
+
updatedAt: Date;
|
|
216
|
+
} | null;
|
|
217
|
+
conversations: {
|
|
218
|
+
id: string;
|
|
219
|
+
title?: string | undefined;
|
|
220
|
+
messages: {
|
|
221
|
+
id: string;
|
|
222
|
+
conversationId: string;
|
|
223
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
224
|
+
content: string;
|
|
225
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
226
|
+
createdAt: Date;
|
|
227
|
+
metadata?: Record<string, unknown> | undefined;
|
|
228
|
+
}[];
|
|
229
|
+
createdAt: Date;
|
|
230
|
+
updatedAt: Date;
|
|
231
|
+
}[];
|
|
232
|
+
isSending: boolean;
|
|
233
|
+
isLoading: boolean;
|
|
234
|
+
isConnected: boolean;
|
|
235
|
+
error: Error | null;
|
|
236
|
+
inputValue: string;
|
|
237
|
+
}>;
|
|
238
|
+
|
|
239
|
+
export { useChat, useChatClient, useChatEvent, useChatState };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
import { Ref } from 'vue';
|
|
3
|
+
import * as _lingshuai_chat_core from '@lingshuai/chat-core';
|
|
4
|
+
import { ChatConfig, Message, Conversation, ChatClient, ChatEventType, ChatEventListener, ChatState } from '@lingshuai/chat-core';
|
|
5
|
+
export { ApiClient, ChatClient, ChatConfig, ChatEventListener, ChatEventMap, ChatEventType, ChatState, Conversation, EventEmitter, Message, MessageRole, MessageStatus, SendMessageRequest, SendMessageResponse, StateListener, StateManager, ThemeConfig, WidgetConfig } from '@lingshuai/chat-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* useChat Composable - 提供完整的聊天功能
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```vue
|
|
12
|
+
* <script setup>
|
|
13
|
+
* import { useChat } from '@lingshuai/chat-vue';
|
|
14
|
+
*
|
|
15
|
+
* const {
|
|
16
|
+
* messages,
|
|
17
|
+
* isSending,
|
|
18
|
+
* input,
|
|
19
|
+
* sendMessage,
|
|
20
|
+
* } = useChat({
|
|
21
|
+
* apiKey: 'your-api-key',
|
|
22
|
+
* appId: 'your-app-id',
|
|
23
|
+
* });
|
|
24
|
+
* </script>
|
|
25
|
+
*
|
|
26
|
+
* <template>
|
|
27
|
+
* <div>
|
|
28
|
+
* <div v-for="msg in messages" :key="msg.id">
|
|
29
|
+
* {{ msg.content }}
|
|
30
|
+
* </div>
|
|
31
|
+
* <input v-model="input" @keydown.enter="sendMessage(input)" />
|
|
32
|
+
* <button @click="sendMessage(input)" :disabled="isSending">发送</button>
|
|
33
|
+
* </div>
|
|
34
|
+
* </template>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function useChat(config: ChatConfig): {
|
|
38
|
+
messages: Ref<{
|
|
39
|
+
id: string;
|
|
40
|
+
conversationId: string;
|
|
41
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
42
|
+
content: string;
|
|
43
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
44
|
+
createdAt: Date;
|
|
45
|
+
metadata?: Record<string, unknown> | undefined;
|
|
46
|
+
}[], Message[] | {
|
|
47
|
+
id: string;
|
|
48
|
+
conversationId: string;
|
|
49
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
50
|
+
content: string;
|
|
51
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
52
|
+
createdAt: Date;
|
|
53
|
+
metadata?: Record<string, unknown> | undefined;
|
|
54
|
+
}[]>;
|
|
55
|
+
conversations: Ref<{
|
|
56
|
+
id: string;
|
|
57
|
+
title?: string | undefined;
|
|
58
|
+
messages: {
|
|
59
|
+
id: string;
|
|
60
|
+
conversationId: string;
|
|
61
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
62
|
+
content: string;
|
|
63
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
64
|
+
createdAt: Date;
|
|
65
|
+
metadata?: Record<string, unknown> | undefined;
|
|
66
|
+
}[];
|
|
67
|
+
createdAt: Date;
|
|
68
|
+
updatedAt: Date;
|
|
69
|
+
}[], Conversation[] | {
|
|
70
|
+
id: string;
|
|
71
|
+
title?: string | undefined;
|
|
72
|
+
messages: {
|
|
73
|
+
id: string;
|
|
74
|
+
conversationId: string;
|
|
75
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
76
|
+
content: string;
|
|
77
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
78
|
+
createdAt: Date;
|
|
79
|
+
metadata?: Record<string, unknown> | undefined;
|
|
80
|
+
}[];
|
|
81
|
+
createdAt: Date;
|
|
82
|
+
updatedAt: Date;
|
|
83
|
+
}[]>;
|
|
84
|
+
currentConversation: Ref<{
|
|
85
|
+
id: string;
|
|
86
|
+
title?: string | undefined;
|
|
87
|
+
messages: {
|
|
88
|
+
id: string;
|
|
89
|
+
conversationId: string;
|
|
90
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
91
|
+
content: string;
|
|
92
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
93
|
+
createdAt: Date;
|
|
94
|
+
metadata?: Record<string, unknown> | undefined;
|
|
95
|
+
}[];
|
|
96
|
+
createdAt: Date;
|
|
97
|
+
updatedAt: Date;
|
|
98
|
+
} | null, Conversation | {
|
|
99
|
+
id: string;
|
|
100
|
+
title?: string | undefined;
|
|
101
|
+
messages: {
|
|
102
|
+
id: string;
|
|
103
|
+
conversationId: string;
|
|
104
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
105
|
+
content: string;
|
|
106
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
107
|
+
createdAt: Date;
|
|
108
|
+
metadata?: Record<string, unknown> | undefined;
|
|
109
|
+
}[];
|
|
110
|
+
createdAt: Date;
|
|
111
|
+
updatedAt: Date;
|
|
112
|
+
} | null>;
|
|
113
|
+
isSending: Ref<boolean, boolean>;
|
|
114
|
+
isLoading: Ref<boolean, boolean>;
|
|
115
|
+
error: Ref<Error | null, Error | null>;
|
|
116
|
+
input: Ref<string, string>;
|
|
117
|
+
sendMessage: (content: string) => Promise<void>;
|
|
118
|
+
abort: () => void;
|
|
119
|
+
newConversation: () => void;
|
|
120
|
+
switchConversation: (conversationId: string) => Promise<void>;
|
|
121
|
+
deleteConversation: (conversationId: string) => Promise<void>;
|
|
122
|
+
getConversations: () => Promise<never[] | Conversation[]>;
|
|
123
|
+
client: vue.ShallowRef<ChatClient | null, ChatClient | null>;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* useChatClient Composable - 创建 ChatClient 实例
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```vue
|
|
130
|
+
* <script setup>
|
|
131
|
+
* import { useChatClient } from '@lingshuai/chat-vue';
|
|
132
|
+
*
|
|
133
|
+
* const client = useChatClient({
|
|
134
|
+
* apiKey: 'your-api-key',
|
|
135
|
+
* appId: 'your-app-id',
|
|
136
|
+
* });
|
|
137
|
+
*
|
|
138
|
+
* client.on('message:received', ({ message }) => {
|
|
139
|
+
* console.log('收到消息:', message.content);
|
|
140
|
+
* });
|
|
141
|
+
* </script>
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare function useChatClient(config: ChatConfig): Ref<ChatClient | null>;
|
|
145
|
+
/**
|
|
146
|
+
* useChatEvent Composable - 监听聊天事件
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```vue
|
|
150
|
+
* <script setup>
|
|
151
|
+
* import { useChatClient, useChatEvent } from '@lingshuai/chat-vue';
|
|
152
|
+
*
|
|
153
|
+
* const client = useChatClient({ apiKey: 'xxx', appId: 'xxx' });
|
|
154
|
+
*
|
|
155
|
+
* useChatEvent(client, 'message:stream:chunk', ({ fullContent }) => {
|
|
156
|
+
* console.log('流式内容:', fullContent);
|
|
157
|
+
* });
|
|
158
|
+
* </script>
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
declare function useChatEvent<T extends ChatEventType>(client: Ref<ChatClient | null>, event: T, listener: ChatEventListener<T>): void;
|
|
162
|
+
/**
|
|
163
|
+
* useChatState Composable - 订阅聊天状态
|
|
164
|
+
*/
|
|
165
|
+
declare function useChatState(client: Ref<ChatClient | null>): Ref<{
|
|
166
|
+
currentConversation: {
|
|
167
|
+
id: string;
|
|
168
|
+
title?: string | undefined;
|
|
169
|
+
messages: {
|
|
170
|
+
id: string;
|
|
171
|
+
conversationId: string;
|
|
172
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
173
|
+
content: string;
|
|
174
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
175
|
+
createdAt: Date;
|
|
176
|
+
metadata?: Record<string, unknown> | undefined;
|
|
177
|
+
}[];
|
|
178
|
+
createdAt: Date;
|
|
179
|
+
updatedAt: Date;
|
|
180
|
+
} | null;
|
|
181
|
+
conversations: {
|
|
182
|
+
id: string;
|
|
183
|
+
title?: string | undefined;
|
|
184
|
+
messages: {
|
|
185
|
+
id: string;
|
|
186
|
+
conversationId: string;
|
|
187
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
188
|
+
content: string;
|
|
189
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
190
|
+
createdAt: Date;
|
|
191
|
+
metadata?: Record<string, unknown> | undefined;
|
|
192
|
+
}[];
|
|
193
|
+
createdAt: Date;
|
|
194
|
+
updatedAt: Date;
|
|
195
|
+
}[];
|
|
196
|
+
isSending: boolean;
|
|
197
|
+
isLoading: boolean;
|
|
198
|
+
isConnected: boolean;
|
|
199
|
+
error: Error | null;
|
|
200
|
+
inputValue: string;
|
|
201
|
+
}, ChatState | {
|
|
202
|
+
currentConversation: {
|
|
203
|
+
id: string;
|
|
204
|
+
title?: string | undefined;
|
|
205
|
+
messages: {
|
|
206
|
+
id: string;
|
|
207
|
+
conversationId: string;
|
|
208
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
209
|
+
content: string;
|
|
210
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
211
|
+
createdAt: Date;
|
|
212
|
+
metadata?: Record<string, unknown> | undefined;
|
|
213
|
+
}[];
|
|
214
|
+
createdAt: Date;
|
|
215
|
+
updatedAt: Date;
|
|
216
|
+
} | null;
|
|
217
|
+
conversations: {
|
|
218
|
+
id: string;
|
|
219
|
+
title?: string | undefined;
|
|
220
|
+
messages: {
|
|
221
|
+
id: string;
|
|
222
|
+
conversationId: string;
|
|
223
|
+
role: _lingshuai_chat_core.MessageRole;
|
|
224
|
+
content: string;
|
|
225
|
+
status: _lingshuai_chat_core.MessageStatus;
|
|
226
|
+
createdAt: Date;
|
|
227
|
+
metadata?: Record<string, unknown> | undefined;
|
|
228
|
+
}[];
|
|
229
|
+
createdAt: Date;
|
|
230
|
+
updatedAt: Date;
|
|
231
|
+
}[];
|
|
232
|
+
isSending: boolean;
|
|
233
|
+
isLoading: boolean;
|
|
234
|
+
isConnected: boolean;
|
|
235
|
+
error: Error | null;
|
|
236
|
+
inputValue: string;
|
|
237
|
+
}>;
|
|
238
|
+
|
|
239
|
+
export { useChat, useChatClient, useChatEvent, useChatState };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vue = require('vue');
|
|
4
|
+
var chatCore = require('@lingshuai/chat-core');
|
|
5
|
+
|
|
6
|
+
// src/composables.ts
|
|
7
|
+
function useChat(config) {
|
|
8
|
+
const client = vue.shallowRef(null);
|
|
9
|
+
const messages = vue.ref([]);
|
|
10
|
+
const conversations = vue.ref([]);
|
|
11
|
+
const currentConversation = vue.ref(null);
|
|
12
|
+
const isSending = vue.ref(false);
|
|
13
|
+
const isLoading = vue.ref(false);
|
|
14
|
+
const error = vue.ref(null);
|
|
15
|
+
const input = vue.ref("");
|
|
16
|
+
vue.onMounted(() => {
|
|
17
|
+
client.value = new chatCore.ChatClient(config);
|
|
18
|
+
client.value.subscribe((state) => {
|
|
19
|
+
messages.value = state.currentConversation?.messages || [];
|
|
20
|
+
conversations.value = state.conversations;
|
|
21
|
+
currentConversation.value = state.currentConversation;
|
|
22
|
+
isSending.value = state.isSending;
|
|
23
|
+
isLoading.value = state.isLoading;
|
|
24
|
+
error.value = state.error;
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
vue.onUnmounted(() => {
|
|
28
|
+
client.value?.destroy();
|
|
29
|
+
});
|
|
30
|
+
async function sendMessage(content) {
|
|
31
|
+
if (!client.value || !content.trim()) return;
|
|
32
|
+
await client.value.send(content);
|
|
33
|
+
input.value = "";
|
|
34
|
+
}
|
|
35
|
+
function abort() {
|
|
36
|
+
client.value?.abortAll();
|
|
37
|
+
}
|
|
38
|
+
function newConversation() {
|
|
39
|
+
client.value?.newConversation();
|
|
40
|
+
}
|
|
41
|
+
async function switchConversation(conversationId) {
|
|
42
|
+
await client.value?.switchConversation(conversationId);
|
|
43
|
+
}
|
|
44
|
+
async function deleteConversation(conversationId) {
|
|
45
|
+
await client.value?.deleteConversation(conversationId);
|
|
46
|
+
}
|
|
47
|
+
async function getConversations() {
|
|
48
|
+
return client.value?.getConversations() || [];
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
// 状态(响应式)
|
|
52
|
+
messages,
|
|
53
|
+
conversations,
|
|
54
|
+
currentConversation,
|
|
55
|
+
isSending,
|
|
56
|
+
isLoading,
|
|
57
|
+
error,
|
|
58
|
+
input,
|
|
59
|
+
// 方法
|
|
60
|
+
sendMessage,
|
|
61
|
+
abort,
|
|
62
|
+
newConversation,
|
|
63
|
+
switchConversation,
|
|
64
|
+
deleteConversation,
|
|
65
|
+
getConversations,
|
|
66
|
+
// Client 实例(高级用法)
|
|
67
|
+
client
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function useChatClient(config) {
|
|
71
|
+
const client = vue.shallowRef(null);
|
|
72
|
+
vue.onMounted(() => {
|
|
73
|
+
client.value = new chatCore.ChatClient(config);
|
|
74
|
+
});
|
|
75
|
+
vue.onUnmounted(() => {
|
|
76
|
+
client.value?.destroy();
|
|
77
|
+
});
|
|
78
|
+
return client;
|
|
79
|
+
}
|
|
80
|
+
function useChatEvent(client, event, listener) {
|
|
81
|
+
let unsubscribe = null;
|
|
82
|
+
vue.watch(
|
|
83
|
+
client,
|
|
84
|
+
(newClient) => {
|
|
85
|
+
unsubscribe?.();
|
|
86
|
+
if (newClient) {
|
|
87
|
+
unsubscribe = newClient.on(event, listener);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{ immediate: true }
|
|
91
|
+
);
|
|
92
|
+
vue.onUnmounted(() => {
|
|
93
|
+
unsubscribe?.();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function useChatState(client) {
|
|
97
|
+
const state = vue.ref({
|
|
98
|
+
currentConversation: null,
|
|
99
|
+
conversations: [],
|
|
100
|
+
isSending: false,
|
|
101
|
+
isLoading: false,
|
|
102
|
+
isConnected: false,
|
|
103
|
+
error: null,
|
|
104
|
+
inputValue: ""
|
|
105
|
+
});
|
|
106
|
+
let unsubscribe = null;
|
|
107
|
+
vue.watch(
|
|
108
|
+
client,
|
|
109
|
+
(newClient) => {
|
|
110
|
+
unsubscribe?.();
|
|
111
|
+
if (newClient) {
|
|
112
|
+
state.value = newClient.getState();
|
|
113
|
+
unsubscribe = newClient.subscribe((newState) => {
|
|
114
|
+
state.value = newState;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{ immediate: true }
|
|
119
|
+
);
|
|
120
|
+
vue.onUnmounted(() => {
|
|
121
|
+
unsubscribe?.();
|
|
122
|
+
});
|
|
123
|
+
return state;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Object.defineProperty(exports, "ApiClient", {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
get: function () { return chatCore.ApiClient; }
|
|
129
|
+
});
|
|
130
|
+
Object.defineProperty(exports, "ChatClient", {
|
|
131
|
+
enumerable: true,
|
|
132
|
+
get: function () { return chatCore.ChatClient; }
|
|
133
|
+
});
|
|
134
|
+
Object.defineProperty(exports, "EventEmitter", {
|
|
135
|
+
enumerable: true,
|
|
136
|
+
get: function () { return chatCore.EventEmitter; }
|
|
137
|
+
});
|
|
138
|
+
Object.defineProperty(exports, "StateManager", {
|
|
139
|
+
enumerable: true,
|
|
140
|
+
get: function () { return chatCore.StateManager; }
|
|
141
|
+
});
|
|
142
|
+
exports.useChat = useChat;
|
|
143
|
+
exports.useChatClient = useChatClient;
|
|
144
|
+
exports.useChatEvent = useChatEvent;
|
|
145
|
+
exports.useChatState = useChatState;
|
|
146
|
+
//# sourceMappingURL=index.js.map
|
|
147
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/composables.ts"],"names":["shallowRef","ref","onMounted","ChatClient","onUnmounted","watch"],"mappings":";;;;;;AAyCO,SAAS,QAAQ,MAAA,EAAoB;AAC1C,EAAA,MAAM,MAAA,GAASA,eAA8B,IAAI,CAAA;AACjD,EAAA,MAAM,QAAA,GAAWC,OAAA,CAAe,EAAE,CAAA;AAClC,EAAA,MAAM,aAAA,GAAgBA,OAAA,CAAoB,EAAE,CAAA;AAC5C,EAAA,MAAM,mBAAA,GAAsBA,QAAyB,IAAI,CAAA;AACzD,EAAA,MAAM,SAAA,GAAYA,QAAI,KAAK,CAAA;AAC3B,EAAA,MAAM,SAAA,GAAYA,QAAI,KAAK,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQA,QAAkB,IAAI,CAAA;AACpC,EAAA,MAAM,KAAA,GAAQA,QAAI,EAAE,CAAA;AAGpB,EAAAC,aAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAIC,mBAAA,CAAW,MAAM,CAAA;AAGpC,IAAA,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,CAAC,KAAA,KAAU;AAChC,MAAA,QAAA,CAAS,KAAA,GAAQ,KAAA,CAAM,mBAAA,EAAqB,QAAA,IAAY,EAAC;AACzD,MAAA,aAAA,CAAc,QAAQ,KAAA,CAAM,aAAA;AAC5B,MAAA,mBAAA,CAAoB,QAAQ,KAAA,CAAM,mBAAA;AAClC,MAAA,SAAA,CAAU,QAAQ,KAAA,CAAM,SAAA;AACxB,MAAA,SAAA,CAAU,QAAQ,KAAA,CAAM,SAAA;AACxB,MAAA,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AAGD,EAAAC,eAAA,CAAY,MAAM;AAChB,IAAA,MAAA,CAAO,OAAO,OAAA,EAAQ;AAAA,EACxB,CAAC,CAAA;AAGD,EAAA,eAAe,YAAY,OAAA,EAAiB;AAC1C,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,CAAC,OAAA,CAAQ,MAAK,EAAG;AACtC,IAAA,MAAM,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAC/B,IAAA,KAAA,CAAM,KAAA,GAAQ,EAAA;AAAA,EAChB;AAGA,EAAA,SAAS,KAAA,GAAQ;AACf,IAAA,MAAA,CAAO,OAAO,QAAA,EAAS;AAAA,EACzB;AAGA,EAAA,SAAS,eAAA,GAAkB;AACzB,IAAA,MAAA,CAAO,OAAO,eAAA,EAAgB;AAAA,EAChC;AAGA,EAAA,eAAe,mBAAmB,cAAA,EAAwB;AACxD,IAAA,MAAM,MAAA,CAAO,KAAA,EAAO,kBAAA,CAAmB,cAAc,CAAA;AAAA,EACvD;AAGA,EAAA,eAAe,mBAAmB,cAAA,EAAwB;AACxD,IAAA,MAAM,MAAA,CAAO,KAAA,EAAO,kBAAA,CAAmB,cAAc,CAAA;AAAA,EACvD;AAGA,EAAA,eAAe,gBAAA,GAAmB;AAChC,IAAA,OAAO,MAAA,CAAO,KAAA,EAAO,gBAAA,EAAiB,IAAK,EAAC;AAAA,EAC9C;AAEA,EAAA,OAAO;AAAA;AAAA,IAEL,QAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA;AAAA,IAGA,WAAA;AAAA,IACA,KAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA,gBAAA;AAAA;AAAA,IAGA;AAAA,GACF;AACF;AAqBO,SAAS,cAAc,MAAA,EAA4C;AACxE,EAAA,MAAM,MAAA,GAASJ,eAA8B,IAAI,CAAA;AAEjD,EAAAE,aAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAIC,mBAAA,CAAW,MAAM,CAAA;AAAA,EACtC,CAAC,CAAA;AAED,EAAAC,eAAA,CAAY,MAAM;AAChB,IAAA,MAAA,CAAO,OAAO,OAAA,EAAQ;AAAA,EACxB,CAAC,CAAA;AAED,EAAA,OAAO,MAAA;AACT;AAkBO,SAAS,YAAA,CACd,MAAA,EACA,KAAA,EACA,QAAA,EACA;AACA,EAAA,IAAI,WAAA,GAAmC,IAAA;AAEvC,EAAAC,SAAA;AAAA,IACE,MAAA;AAAA,IACA,CAAC,SAAA,KAAc;AAEb,MAAA,WAAA,IAAc;AAGd,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,WAAA,GAAc,SAAA,CAAU,EAAA,CAAG,KAAA,EAAO,QAAQ,CAAA;AAAA,MAC5C;AAAA,IACF,CAAA;AAAA,IACA,EAAE,WAAW,IAAA;AAAK,GACpB;AAEA,EAAAD,eAAA,CAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AAAA,EAChB,CAAC,CAAA;AACH;AAKO,SAAS,aAAa,MAAA,EAAgC;AAC3D,EAAA,MAAM,QAAQH,OAAA,CAAe;AAAA,IAC3B,mBAAA,EAAqB,IAAA;AAAA,IACrB,eAAe,EAAC;AAAA,IAChB,SAAA,EAAW,KAAA;AAAA,IACX,SAAA,EAAW,KAAA;AAAA,IACX,WAAA,EAAa,KAAA;AAAA,IACb,KAAA,EAAO,IAAA;AAAA,IACP,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,IAAI,WAAA,GAAmC,IAAA;AAEvC,EAAAI,SAAA;AAAA,IACE,MAAA;AAAA,IACA,CAAC,SAAA,KAAc;AACb,MAAA,WAAA,IAAc;AAEd,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,KAAA,CAAM,KAAA,GAAQ,UAAU,QAAA,EAAS;AACjC,QAAA,WAAA,GAAc,SAAA,CAAU,SAAA,CAAU,CAAC,QAAA,KAAa;AAC9C,UAAA,KAAA,CAAM,KAAA,GAAQ,QAAA;AAAA,QAChB,CAAC,CAAA;AAAA,MACH;AAAA,IACF,CAAA;AAAA,IACA,EAAE,WAAW,IAAA;AAAK,GACpB;AAEA,EAAAD,eAAA,CAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AAAA,EAChB,CAAC,CAAA;AAED,EAAA,OAAO,KAAA;AACT","file":"index.js","sourcesContent":["import { ref, shallowRef, onMounted, onUnmounted, watch, Ref } from 'vue';\nimport {\n ChatClient,\n ChatConfig,\n ChatState,\n Message,\n Conversation,\n ChatEventType,\n ChatEventListener,\n} from '@lingshuai/chat-core';\n\n/**\n * useChat Composable - 提供完整的聊天功能\n *\n * @example\n * ```vue\n * <script setup>\n * import { useChat } from '@lingshuai/chat-vue';\n *\n * const {\n * messages,\n * isSending,\n * input,\n * sendMessage,\n * } = useChat({\n * apiKey: 'your-api-key',\n * appId: 'your-app-id',\n * });\n * </script>\n *\n * <template>\n * <div>\n * <div v-for=\"msg in messages\" :key=\"msg.id\">\n * {{ msg.content }}\n * </div>\n * <input v-model=\"input\" @keydown.enter=\"sendMessage(input)\" />\n * <button @click=\"sendMessage(input)\" :disabled=\"isSending\">发送</button>\n * </div>\n * </template>\n * ```\n */\nexport function useChat(config: ChatConfig) {\n const client = shallowRef<ChatClient | null>(null);\n const messages = ref<Message[]>([]);\n const conversations = ref<Conversation[]>([]);\n const currentConversation = ref<Conversation | null>(null);\n const isSending = ref(false);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n const input = ref('');\n\n // 初始化\n onMounted(() => {\n client.value = new ChatClient(config);\n\n // 订阅状态变更\n client.value.subscribe((state) => {\n messages.value = state.currentConversation?.messages || [];\n conversations.value = state.conversations;\n currentConversation.value = state.currentConversation;\n isSending.value = state.isSending;\n isLoading.value = state.isLoading;\n error.value = state.error;\n });\n });\n\n // 清理\n onUnmounted(() => {\n client.value?.destroy();\n });\n\n // 发送消息\n async function sendMessage(content: string) {\n if (!client.value || !content.trim()) return;\n await client.value.send(content);\n input.value = '';\n }\n\n // 取消发送\n function abort() {\n client.value?.abortAll();\n }\n\n // 新建会话\n function newConversation() {\n client.value?.newConversation();\n }\n\n // 切换会话\n async function switchConversation(conversationId: string) {\n await client.value?.switchConversation(conversationId);\n }\n\n // 删除会话\n async function deleteConversation(conversationId: string) {\n await client.value?.deleteConversation(conversationId);\n }\n\n // 获取会话列表\n async function getConversations() {\n return client.value?.getConversations() || [];\n }\n\n return {\n // 状态(响应式)\n messages,\n conversations,\n currentConversation,\n isSending,\n isLoading,\n error,\n input,\n\n // 方法\n sendMessage,\n abort,\n newConversation,\n switchConversation,\n deleteConversation,\n getConversations,\n\n // Client 实例(高级用法)\n client,\n };\n}\n\n/**\n * useChatClient Composable - 创建 ChatClient 实例\n *\n * @example\n * ```vue\n * <script setup>\n * import { useChatClient } from '@lingshuai/chat-vue';\n *\n * const client = useChatClient({\n * apiKey: 'your-api-key',\n * appId: 'your-app-id',\n * });\n *\n * client.on('message:received', ({ message }) => {\n * console.log('收到消息:', message.content);\n * });\n * </script>\n * ```\n */\nexport function useChatClient(config: ChatConfig): Ref<ChatClient | null> {\n const client = shallowRef<ChatClient | null>(null);\n\n onMounted(() => {\n client.value = new ChatClient(config);\n });\n\n onUnmounted(() => {\n client.value?.destroy();\n });\n\n return client;\n}\n\n/**\n * useChatEvent Composable - 监听聊天事件\n *\n * @example\n * ```vue\n * <script setup>\n * import { useChatClient, useChatEvent } from '@lingshuai/chat-vue';\n *\n * const client = useChatClient({ apiKey: 'xxx', appId: 'xxx' });\n *\n * useChatEvent(client, 'message:stream:chunk', ({ fullContent }) => {\n * console.log('流式内容:', fullContent);\n * });\n * </script>\n * ```\n */\nexport function useChatEvent<T extends ChatEventType>(\n client: Ref<ChatClient | null>,\n event: T,\n listener: ChatEventListener<T>\n) {\n let unsubscribe: (() => void) | null = null;\n\n watch(\n client,\n (newClient) => {\n // 清理旧的订阅\n unsubscribe?.();\n\n // 建立新的订阅\n if (newClient) {\n unsubscribe = newClient.on(event, listener);\n }\n },\n { immediate: true }\n );\n\n onUnmounted(() => {\n unsubscribe?.();\n });\n}\n\n/**\n * useChatState Composable - 订阅聊天状态\n */\nexport function useChatState(client: Ref<ChatClient | null>) {\n const state = ref<ChatState>({\n currentConversation: null,\n conversations: [],\n isSending: false,\n isLoading: false,\n isConnected: false,\n error: null,\n inputValue: '',\n });\n\n let unsubscribe: (() => void) | null = null;\n\n watch(\n client,\n (newClient) => {\n unsubscribe?.();\n\n if (newClient) {\n state.value = newClient.getState();\n unsubscribe = newClient.subscribe((newState) => {\n state.value = newState;\n });\n }\n },\n { immediate: true }\n );\n\n onUnmounted(() => {\n unsubscribe?.();\n });\n\n return state;\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { shallowRef, ref, onMounted, onUnmounted, watch } from 'vue';
|
|
2
|
+
import { ChatClient } from '@lingshuai/chat-core';
|
|
3
|
+
export { ApiClient, ChatClient, EventEmitter, StateManager } from '@lingshuai/chat-core';
|
|
4
|
+
|
|
5
|
+
// src/composables.ts
|
|
6
|
+
function useChat(config) {
|
|
7
|
+
const client = shallowRef(null);
|
|
8
|
+
const messages = ref([]);
|
|
9
|
+
const conversations = ref([]);
|
|
10
|
+
const currentConversation = ref(null);
|
|
11
|
+
const isSending = ref(false);
|
|
12
|
+
const isLoading = ref(false);
|
|
13
|
+
const error = ref(null);
|
|
14
|
+
const input = ref("");
|
|
15
|
+
onMounted(() => {
|
|
16
|
+
client.value = new ChatClient(config);
|
|
17
|
+
client.value.subscribe((state) => {
|
|
18
|
+
messages.value = state.currentConversation?.messages || [];
|
|
19
|
+
conversations.value = state.conversations;
|
|
20
|
+
currentConversation.value = state.currentConversation;
|
|
21
|
+
isSending.value = state.isSending;
|
|
22
|
+
isLoading.value = state.isLoading;
|
|
23
|
+
error.value = state.error;
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
onUnmounted(() => {
|
|
27
|
+
client.value?.destroy();
|
|
28
|
+
});
|
|
29
|
+
async function sendMessage(content) {
|
|
30
|
+
if (!client.value || !content.trim()) return;
|
|
31
|
+
await client.value.send(content);
|
|
32
|
+
input.value = "";
|
|
33
|
+
}
|
|
34
|
+
function abort() {
|
|
35
|
+
client.value?.abortAll();
|
|
36
|
+
}
|
|
37
|
+
function newConversation() {
|
|
38
|
+
client.value?.newConversation();
|
|
39
|
+
}
|
|
40
|
+
async function switchConversation(conversationId) {
|
|
41
|
+
await client.value?.switchConversation(conversationId);
|
|
42
|
+
}
|
|
43
|
+
async function deleteConversation(conversationId) {
|
|
44
|
+
await client.value?.deleteConversation(conversationId);
|
|
45
|
+
}
|
|
46
|
+
async function getConversations() {
|
|
47
|
+
return client.value?.getConversations() || [];
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
// 状态(响应式)
|
|
51
|
+
messages,
|
|
52
|
+
conversations,
|
|
53
|
+
currentConversation,
|
|
54
|
+
isSending,
|
|
55
|
+
isLoading,
|
|
56
|
+
error,
|
|
57
|
+
input,
|
|
58
|
+
// 方法
|
|
59
|
+
sendMessage,
|
|
60
|
+
abort,
|
|
61
|
+
newConversation,
|
|
62
|
+
switchConversation,
|
|
63
|
+
deleteConversation,
|
|
64
|
+
getConversations,
|
|
65
|
+
// Client 实例(高级用法)
|
|
66
|
+
client
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function useChatClient(config) {
|
|
70
|
+
const client = shallowRef(null);
|
|
71
|
+
onMounted(() => {
|
|
72
|
+
client.value = new ChatClient(config);
|
|
73
|
+
});
|
|
74
|
+
onUnmounted(() => {
|
|
75
|
+
client.value?.destroy();
|
|
76
|
+
});
|
|
77
|
+
return client;
|
|
78
|
+
}
|
|
79
|
+
function useChatEvent(client, event, listener) {
|
|
80
|
+
let unsubscribe = null;
|
|
81
|
+
watch(
|
|
82
|
+
client,
|
|
83
|
+
(newClient) => {
|
|
84
|
+
unsubscribe?.();
|
|
85
|
+
if (newClient) {
|
|
86
|
+
unsubscribe = newClient.on(event, listener);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
{ immediate: true }
|
|
90
|
+
);
|
|
91
|
+
onUnmounted(() => {
|
|
92
|
+
unsubscribe?.();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function useChatState(client) {
|
|
96
|
+
const state = ref({
|
|
97
|
+
currentConversation: null,
|
|
98
|
+
conversations: [],
|
|
99
|
+
isSending: false,
|
|
100
|
+
isLoading: false,
|
|
101
|
+
isConnected: false,
|
|
102
|
+
error: null,
|
|
103
|
+
inputValue: ""
|
|
104
|
+
});
|
|
105
|
+
let unsubscribe = null;
|
|
106
|
+
watch(
|
|
107
|
+
client,
|
|
108
|
+
(newClient) => {
|
|
109
|
+
unsubscribe?.();
|
|
110
|
+
if (newClient) {
|
|
111
|
+
state.value = newClient.getState();
|
|
112
|
+
unsubscribe = newClient.subscribe((newState) => {
|
|
113
|
+
state.value = newState;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{ immediate: true }
|
|
118
|
+
);
|
|
119
|
+
onUnmounted(() => {
|
|
120
|
+
unsubscribe?.();
|
|
121
|
+
});
|
|
122
|
+
return state;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { useChat, useChatClient, useChatEvent, useChatState };
|
|
126
|
+
//# sourceMappingURL=index.mjs.map
|
|
127
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/composables.ts"],"names":[],"mappings":";;;;;AAyCO,SAAS,QAAQ,MAAA,EAAoB;AAC1C,EAAA,MAAM,MAAA,GAAS,WAA8B,IAAI,CAAA;AACjD,EAAA,MAAM,QAAA,GAAW,GAAA,CAAe,EAAE,CAAA;AAClC,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAoB,EAAE,CAAA;AAC5C,EAAA,MAAM,mBAAA,GAAsB,IAAyB,IAAI,CAAA;AACzD,EAAA,MAAM,SAAA,GAAY,IAAI,KAAK,CAAA;AAC3B,EAAA,MAAM,SAAA,GAAY,IAAI,KAAK,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,IAAkB,IAAI,CAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,IAAI,EAAE,CAAA;AAGpB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AAGpC,IAAA,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,CAAC,KAAA,KAAU;AAChC,MAAA,QAAA,CAAS,KAAA,GAAQ,KAAA,CAAM,mBAAA,EAAqB,QAAA,IAAY,EAAC;AACzD,MAAA,aAAA,CAAc,QAAQ,KAAA,CAAM,aAAA;AAC5B,MAAA,mBAAA,CAAoB,QAAQ,KAAA,CAAM,mBAAA;AAClC,MAAA,SAAA,CAAU,QAAQ,KAAA,CAAM,SAAA;AACxB,MAAA,SAAA,CAAU,QAAQ,KAAA,CAAM,SAAA;AACxB,MAAA,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AAGD,EAAA,WAAA,CAAY,MAAM;AAChB,IAAA,MAAA,CAAO,OAAO,OAAA,EAAQ;AAAA,EACxB,CAAC,CAAA;AAGD,EAAA,eAAe,YAAY,OAAA,EAAiB;AAC1C,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,CAAC,OAAA,CAAQ,MAAK,EAAG;AACtC,IAAA,MAAM,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAC/B,IAAA,KAAA,CAAM,KAAA,GAAQ,EAAA;AAAA,EAChB;AAGA,EAAA,SAAS,KAAA,GAAQ;AACf,IAAA,MAAA,CAAO,OAAO,QAAA,EAAS;AAAA,EACzB;AAGA,EAAA,SAAS,eAAA,GAAkB;AACzB,IAAA,MAAA,CAAO,OAAO,eAAA,EAAgB;AAAA,EAChC;AAGA,EAAA,eAAe,mBAAmB,cAAA,EAAwB;AACxD,IAAA,MAAM,MAAA,CAAO,KAAA,EAAO,kBAAA,CAAmB,cAAc,CAAA;AAAA,EACvD;AAGA,EAAA,eAAe,mBAAmB,cAAA,EAAwB;AACxD,IAAA,MAAM,MAAA,CAAO,KAAA,EAAO,kBAAA,CAAmB,cAAc,CAAA;AAAA,EACvD;AAGA,EAAA,eAAe,gBAAA,GAAmB;AAChC,IAAA,OAAO,MAAA,CAAO,KAAA,EAAO,gBAAA,EAAiB,IAAK,EAAC;AAAA,EAC9C;AAEA,EAAA,OAAO;AAAA;AAAA,IAEL,QAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA;AAAA,IAGA,WAAA;AAAA,IACA,KAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA,gBAAA;AAAA;AAAA,IAGA;AAAA,GACF;AACF;AAqBO,SAAS,cAAc,MAAA,EAA4C;AACxE,EAAA,MAAM,MAAA,GAAS,WAA8B,IAAI,CAAA;AAEjD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AAAA,EACtC,CAAC,CAAA;AAED,EAAA,WAAA,CAAY,MAAM;AAChB,IAAA,MAAA,CAAO,OAAO,OAAA,EAAQ;AAAA,EACxB,CAAC,CAAA;AAED,EAAA,OAAO,MAAA;AACT;AAkBO,SAAS,YAAA,CACd,MAAA,EACA,KAAA,EACA,QAAA,EACA;AACA,EAAA,IAAI,WAAA,GAAmC,IAAA;AAEvC,EAAA,KAAA;AAAA,IACE,MAAA;AAAA,IACA,CAAC,SAAA,KAAc;AAEb,MAAA,WAAA,IAAc;AAGd,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,WAAA,GAAc,SAAA,CAAU,EAAA,CAAG,KAAA,EAAO,QAAQ,CAAA;AAAA,MAC5C;AAAA,IACF,CAAA;AAAA,IACA,EAAE,WAAW,IAAA;AAAK,GACpB;AAEA,EAAA,WAAA,CAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AAAA,EAChB,CAAC,CAAA;AACH;AAKO,SAAS,aAAa,MAAA,EAAgC;AAC3D,EAAA,MAAM,QAAQ,GAAA,CAAe;AAAA,IAC3B,mBAAA,EAAqB,IAAA;AAAA,IACrB,eAAe,EAAC;AAAA,IAChB,SAAA,EAAW,KAAA;AAAA,IACX,SAAA,EAAW,KAAA;AAAA,IACX,WAAA,EAAa,KAAA;AAAA,IACb,KAAA,EAAO,IAAA;AAAA,IACP,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,IAAI,WAAA,GAAmC,IAAA;AAEvC,EAAA,KAAA;AAAA,IACE,MAAA;AAAA,IACA,CAAC,SAAA,KAAc;AACb,MAAA,WAAA,IAAc;AAEd,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,KAAA,CAAM,KAAA,GAAQ,UAAU,QAAA,EAAS;AACjC,QAAA,WAAA,GAAc,SAAA,CAAU,SAAA,CAAU,CAAC,QAAA,KAAa;AAC9C,UAAA,KAAA,CAAM,KAAA,GAAQ,QAAA;AAAA,QAChB,CAAC,CAAA;AAAA,MACH;AAAA,IACF,CAAA;AAAA,IACA,EAAE,WAAW,IAAA;AAAK,GACpB;AAEA,EAAA,WAAA,CAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AAAA,EAChB,CAAC,CAAA;AAED,EAAA,OAAO,KAAA;AACT","file":"index.mjs","sourcesContent":["import { ref, shallowRef, onMounted, onUnmounted, watch, Ref } from 'vue';\nimport {\n ChatClient,\n ChatConfig,\n ChatState,\n Message,\n Conversation,\n ChatEventType,\n ChatEventListener,\n} from '@lingshuai/chat-core';\n\n/**\n * useChat Composable - 提供完整的聊天功能\n *\n * @example\n * ```vue\n * <script setup>\n * import { useChat } from '@lingshuai/chat-vue';\n *\n * const {\n * messages,\n * isSending,\n * input,\n * sendMessage,\n * } = useChat({\n * apiKey: 'your-api-key',\n * appId: 'your-app-id',\n * });\n * </script>\n *\n * <template>\n * <div>\n * <div v-for=\"msg in messages\" :key=\"msg.id\">\n * {{ msg.content }}\n * </div>\n * <input v-model=\"input\" @keydown.enter=\"sendMessage(input)\" />\n * <button @click=\"sendMessage(input)\" :disabled=\"isSending\">发送</button>\n * </div>\n * </template>\n * ```\n */\nexport function useChat(config: ChatConfig) {\n const client = shallowRef<ChatClient | null>(null);\n const messages = ref<Message[]>([]);\n const conversations = ref<Conversation[]>([]);\n const currentConversation = ref<Conversation | null>(null);\n const isSending = ref(false);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n const input = ref('');\n\n // 初始化\n onMounted(() => {\n client.value = new ChatClient(config);\n\n // 订阅状态变更\n client.value.subscribe((state) => {\n messages.value = state.currentConversation?.messages || [];\n conversations.value = state.conversations;\n currentConversation.value = state.currentConversation;\n isSending.value = state.isSending;\n isLoading.value = state.isLoading;\n error.value = state.error;\n });\n });\n\n // 清理\n onUnmounted(() => {\n client.value?.destroy();\n });\n\n // 发送消息\n async function sendMessage(content: string) {\n if (!client.value || !content.trim()) return;\n await client.value.send(content);\n input.value = '';\n }\n\n // 取消发送\n function abort() {\n client.value?.abortAll();\n }\n\n // 新建会话\n function newConversation() {\n client.value?.newConversation();\n }\n\n // 切换会话\n async function switchConversation(conversationId: string) {\n await client.value?.switchConversation(conversationId);\n }\n\n // 删除会话\n async function deleteConversation(conversationId: string) {\n await client.value?.deleteConversation(conversationId);\n }\n\n // 获取会话列表\n async function getConversations() {\n return client.value?.getConversations() || [];\n }\n\n return {\n // 状态(响应式)\n messages,\n conversations,\n currentConversation,\n isSending,\n isLoading,\n error,\n input,\n\n // 方法\n sendMessage,\n abort,\n newConversation,\n switchConversation,\n deleteConversation,\n getConversations,\n\n // Client 实例(高级用法)\n client,\n };\n}\n\n/**\n * useChatClient Composable - 创建 ChatClient 实例\n *\n * @example\n * ```vue\n * <script setup>\n * import { useChatClient } from '@lingshuai/chat-vue';\n *\n * const client = useChatClient({\n * apiKey: 'your-api-key',\n * appId: 'your-app-id',\n * });\n *\n * client.on('message:received', ({ message }) => {\n * console.log('收到消息:', message.content);\n * });\n * </script>\n * ```\n */\nexport function useChatClient(config: ChatConfig): Ref<ChatClient | null> {\n const client = shallowRef<ChatClient | null>(null);\n\n onMounted(() => {\n client.value = new ChatClient(config);\n });\n\n onUnmounted(() => {\n client.value?.destroy();\n });\n\n return client;\n}\n\n/**\n * useChatEvent Composable - 监听聊天事件\n *\n * @example\n * ```vue\n * <script setup>\n * import { useChatClient, useChatEvent } from '@lingshuai/chat-vue';\n *\n * const client = useChatClient({ apiKey: 'xxx', appId: 'xxx' });\n *\n * useChatEvent(client, 'message:stream:chunk', ({ fullContent }) => {\n * console.log('流式内容:', fullContent);\n * });\n * </script>\n * ```\n */\nexport function useChatEvent<T extends ChatEventType>(\n client: Ref<ChatClient | null>,\n event: T,\n listener: ChatEventListener<T>\n) {\n let unsubscribe: (() => void) | null = null;\n\n watch(\n client,\n (newClient) => {\n // 清理旧的订阅\n unsubscribe?.();\n\n // 建立新的订阅\n if (newClient) {\n unsubscribe = newClient.on(event, listener);\n }\n },\n { immediate: true }\n );\n\n onUnmounted(() => {\n unsubscribe?.();\n });\n}\n\n/**\n * useChatState Composable - 订阅聊天状态\n */\nexport function useChatState(client: Ref<ChatClient | null>) {\n const state = ref<ChatState>({\n currentConversation: null,\n conversations: [],\n isSending: false,\n isLoading: false,\n isConnected: false,\n error: null,\n inputValue: '',\n });\n\n let unsubscribe: (() => void) | null = null;\n\n watch(\n client,\n (newClient) => {\n unsubscribe?.();\n\n if (newClient) {\n state.value = newClient.getState();\n unsubscribe = newClient.subscribe((newState) => {\n state.value = newState;\n });\n }\n },\n { immediate: true }\n );\n\n onUnmounted(() => {\n unsubscribe?.();\n });\n\n return state;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lingshuai/chat-vue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI 对话 SDK Vue 组件 - Vue 3 Composables",
|
|
5
|
+
"author": "LingShuAI Team",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/lingshuai/chat-sdk"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"module": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"require": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@lingshuai/chat-core": "0.1.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"vue": ">=3.3.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"vue": "^3.4.0",
|
|
31
|
+
"tsup": "^8.0.0",
|
|
32
|
+
"typescript": "^5.3.0",
|
|
33
|
+
"rimraf": "^5.0.0"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"ai",
|
|
37
|
+
"chat",
|
|
38
|
+
"vue",
|
|
39
|
+
"sdk",
|
|
40
|
+
"composables",
|
|
41
|
+
"chatbot"
|
|
42
|
+
],
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsup",
|
|
49
|
+
"dev": "tsup --watch",
|
|
50
|
+
"clean": "rimraf dist",
|
|
51
|
+
"typecheck": "tsc --noEmit"
|
|
52
|
+
}
|
|
53
|
+
}
|