@unif/react-native-chat-sdk 0.4.2 → 0.5.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.
Files changed (55) hide show
  1. package/lib/commonjs/hooks/ChatProvider.js +6 -5
  2. package/lib/commonjs/hooks/ChatProvider.js.map +1 -1
  3. package/lib/commonjs/hooks/useXChat.js +3 -11
  4. package/lib/commonjs/hooks/useXChat.js.map +1 -1
  5. package/lib/commonjs/hooks/useXConversations.js +24 -4
  6. package/lib/commonjs/hooks/useXConversations.js.map +1 -1
  7. package/lib/commonjs/index.js +19 -0
  8. package/lib/commonjs/index.js.map +1 -1
  9. package/lib/commonjs/stores/chatStore.js +19 -0
  10. package/lib/commonjs/stores/chatStore.js.map +1 -1
  11. package/lib/commonjs/stores/historyStore.js +26 -0
  12. package/lib/commonjs/stores/historyStore.js.map +1 -1
  13. package/lib/module/hooks/ChatProvider.js +6 -5
  14. package/lib/module/hooks/ChatProvider.js.map +1 -1
  15. package/lib/module/hooks/useXChat.js +5 -13
  16. package/lib/module/hooks/useXChat.js.map +1 -1
  17. package/lib/module/hooks/useXConversations.js +24 -4
  18. package/lib/module/hooks/useXConversations.js.map +1 -1
  19. package/lib/module/index.js +2 -0
  20. package/lib/module/index.js.map +1 -1
  21. package/lib/module/stores/chatStore.js +16 -0
  22. package/lib/module/stores/chatStore.js.map +1 -1
  23. package/lib/module/stores/historyStore.js +26 -0
  24. package/lib/module/stores/historyStore.js.map +1 -1
  25. package/lib/typescript/commonjs/hooks/ChatProvider.d.ts +3 -2
  26. package/lib/typescript/commonjs/hooks/ChatProvider.d.ts.map +1 -1
  27. package/lib/typescript/commonjs/hooks/useXChat.d.ts +1 -2
  28. package/lib/typescript/commonjs/hooks/useXChat.d.ts.map +1 -1
  29. package/lib/typescript/commonjs/hooks/useXConversations.d.ts +3 -0
  30. package/lib/typescript/commonjs/hooks/useXConversations.d.ts.map +1 -1
  31. package/lib/typescript/commonjs/index.d.ts +1 -0
  32. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/stores/chatStore.d.ts +3 -0
  34. package/lib/typescript/commonjs/stores/chatStore.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/stores/historyStore.d.ts +1 -0
  36. package/lib/typescript/commonjs/stores/historyStore.d.ts.map +1 -1
  37. package/lib/typescript/module/hooks/ChatProvider.d.ts +3 -2
  38. package/lib/typescript/module/hooks/ChatProvider.d.ts.map +1 -1
  39. package/lib/typescript/module/hooks/useXChat.d.ts +1 -2
  40. package/lib/typescript/module/hooks/useXChat.d.ts.map +1 -1
  41. package/lib/typescript/module/hooks/useXConversations.d.ts +3 -0
  42. package/lib/typescript/module/hooks/useXConversations.d.ts.map +1 -1
  43. package/lib/typescript/module/index.d.ts +1 -0
  44. package/lib/typescript/module/index.d.ts.map +1 -1
  45. package/lib/typescript/module/stores/chatStore.d.ts +3 -0
  46. package/lib/typescript/module/stores/chatStore.d.ts.map +1 -1
  47. package/lib/typescript/module/stores/historyStore.d.ts +1 -0
  48. package/lib/typescript/module/stores/historyStore.d.ts.map +1 -1
  49. package/package.json +1 -1
  50. package/src/hooks/ChatProvider.tsx +21 -9
  51. package/src/hooks/useXChat.ts +8 -20
  52. package/src/hooks/useXConversations.ts +33 -4
  53. package/src/index.ts +5 -0
  54. package/src/stores/chatStore.ts +20 -0
  55. package/src/stores/historyStore.ts +41 -0
@@ -6,6 +6,7 @@
6
6
 
7
7
  import { useState, useCallback, useEffect, useRef } from 'react';
8
8
  import { createHistoryStore } from '../stores/historyStore';
9
+ import { getOrCreateChatStore } from '../stores/chatStore';
9
10
  import type { ChatStorage } from '../stores/storage';
10
11
  import type { ChatMessage } from '../types/message';
11
12
 
@@ -23,7 +24,7 @@ export function useXConversations(options: UseXConversationsOptions) {
23
24
  const history = historyRef.current;
24
25
 
25
26
  const [sessions, setSessions] = useState(history.sessions);
26
- const [activeId, setActiveId] = useState('');
27
+ const [activeId, setActiveIdState] = useState('');
27
28
 
28
29
  // 初始化加载
29
30
  useEffect(() => {
@@ -36,16 +37,20 @@ export function useXConversations(options: UseXConversationsOptions) {
36
37
  // eslint-disable-next-line react-hooks/exhaustive-deps
37
38
  }, []);
38
39
 
40
+ const setActiveId = useCallback((id: string) => {
41
+ setActiveIdState(id);
42
+ }, []);
43
+
39
44
  const switchSession = useCallback(
40
45
  async (id: string): Promise<ChatMessage[]> => {
41
- setActiveId(id);
46
+ setActiveIdState(id);
42
47
  return await history.loadSessionMessages(id);
43
48
  },
44
49
  [history]
45
50
  );
46
51
 
47
52
  const newSession = useCallback(() => {
48
- setActiveId('');
53
+ setActiveIdState('');
49
54
  }, []);
50
55
 
51
56
  const deleteSession = useCallback(
@@ -53,7 +58,7 @@ export function useXConversations(options: UseXConversationsOptions) {
53
58
  await history.deleteSession(id);
54
59
  setSessions([...history.sessions]);
55
60
  if (activeId === id) {
56
- setActiveId('');
61
+ setActiveIdState('');
57
62
  }
58
63
  },
59
64
  [history, activeId]
@@ -67,6 +72,27 @@ export function useXConversations(options: UseXConversationsOptions) {
67
72
  [history]
68
73
  );
69
74
 
75
+ const saveSession = useCallback(
76
+ async (id: string, title: string, messages: ChatMessage[]) => {
77
+ await history.saveSession(id, title, messages);
78
+ setSessions([...history.sessions]);
79
+ },
80
+ [history]
81
+ );
82
+
83
+ const loadSessionMessages = useCallback(
84
+ async (id: string): Promise<ChatMessage[]> => {
85
+ const msgs = await history.loadSessionMessages(id);
86
+ // 将消息加载到对应的内存 store
87
+ if (msgs.length > 0) {
88
+ const store = getOrCreateChatStore(id);
89
+ store.getState().loadSession(msgs);
90
+ }
91
+ return msgs;
92
+ },
93
+ [history]
94
+ );
95
+
70
96
  const updateSession = useCallback(
71
97
  (id: string, data: Partial<{ title: string }>) => {
72
98
  const session = history.sessions.find((s) => s.id === id);
@@ -81,10 +107,13 @@ export function useXConversations(options: UseXConversationsOptions) {
81
107
  return {
82
108
  sessions,
83
109
  activeId,
110
+ setActiveId,
84
111
  switchSession,
85
112
  newSession,
86
113
  deleteSession,
87
114
  archiveSession,
115
+ saveSession,
116
+ loadSessionMessages,
88
117
  updateSession,
89
118
  };
90
119
  }
package/src/index.ts CHANGED
@@ -47,6 +47,11 @@ export type { DeepSeekChatProviderConfig } from './providers/DeepSeekChatProvide
47
47
 
48
48
  // Stores
49
49
  export type { ChatStorage } from './stores/storage';
50
+ export {
51
+ getOrCreateChatStore,
52
+ deleteChatStore,
53
+ getChatStoreMessages,
54
+ } from './stores/chatStore';
50
55
 
51
56
  // Hooks
52
57
  export { useXChat } from './hooks/useXChat';
@@ -35,6 +35,26 @@ interface ChatState {
35
35
  loadSession: (messages: ChatMessage[]) => void;
36
36
  }
37
37
 
38
+ // 全局 store 管理器 — 多会话内存常驻
39
+ const chatStoreMap = new Map<string, ReturnType<typeof createChatStore>>();
40
+
41
+ export function getOrCreateChatStore(key: string) {
42
+ let store = chatStoreMap.get(key);
43
+ if (!store) {
44
+ store = createChatStore();
45
+ chatStoreMap.set(key, store);
46
+ }
47
+ return store;
48
+ }
49
+
50
+ export function deleteChatStore(key: string) {
51
+ chatStoreMap.delete(key);
52
+ }
53
+
54
+ export function getChatStoreMessages(key: string) {
55
+ return chatStoreMap.get(key)?.getState()?.messages;
56
+ }
57
+
38
58
  export const createChatStore = () =>
39
59
  create<ChatState>((set, get) => ({
40
60
  messages: [],
@@ -24,6 +24,11 @@ export interface HistoryStore {
24
24
  title: string,
25
25
  messages: ChatMessage[]
26
26
  ) => Promise<void>;
27
+ saveSession: (
28
+ id: string,
29
+ title: string,
30
+ messages: ChatMessage[]
31
+ ) => Promise<void>;
27
32
  loadSessionMessages: (id: string) => Promise<ChatMessage[]>;
28
33
  deleteSession: (id: string) => Promise<void>;
29
34
  clearAll: () => Promise<void>;
@@ -88,6 +93,42 @@ export function createHistoryStore(storage: ChatStorage): HistoryStore {
88
93
  await saveIndex();
89
94
  },
90
95
 
96
+ saveSession: async (id, title, messages) => {
97
+ await loadIndex();
98
+ if (messages.length === 0) return;
99
+
100
+ await storage.setItem(
101
+ `${MESSAGE_KEY_PREFIX}${id}`,
102
+ JSON.stringify(messages)
103
+ );
104
+
105
+ const lastMsg = messages[0];
106
+ const summary: SessionSummary = {
107
+ id,
108
+ title,
109
+ lastMessage: lastMsg?.text?.slice(0, 50) ?? '',
110
+ timestamp: Date.now(),
111
+ messageCount: messages.length,
112
+ };
113
+
114
+ const idx = sessions.findIndex((s) => s.id === id);
115
+ if (idx >= 0) {
116
+ sessions[idx] = summary;
117
+ } else {
118
+ sessions.unshift(summary);
119
+ }
120
+
121
+ // FIFO 淘汰
122
+ if (sessions.length > MAX_SESSIONS) {
123
+ const removed = sessions.splice(MAX_SESSIONS);
124
+ await Promise.all(
125
+ removed.map((s) => storage.removeItem(`${MESSAGE_KEY_PREFIX}${s.id}`))
126
+ );
127
+ }
128
+
129
+ await saveIndex();
130
+ },
131
+
91
132
  loadSessionMessages: async (id) => {
92
133
  const raw = await storage.getItem(`${MESSAGE_KEY_PREFIX}${id}`);
93
134
  if (!raw) return [];