hazo_chat 4.0.2 → 4.0.5

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 (155) hide show
  1. package/README.md +46 -6
  2. package/SETUP_CHECKLIST.md +12 -2
  3. package/dist/api/index.d.ts +41 -0
  4. package/dist/api/index.d.ts.map +1 -0
  5. package/dist/api/index.js +40 -0
  6. package/dist/api/index.js.map +1 -0
  7. package/dist/api/messages.d.ts +85 -0
  8. package/dist/api/messages.d.ts.map +1 -0
  9. package/dist/api/messages.js +626 -0
  10. package/dist/api/messages.js.map +1 -0
  11. package/dist/api/types.d.ts +134 -0
  12. package/dist/api/types.d.ts.map +1 -0
  13. package/dist/api/types.js +8 -0
  14. package/dist/api/types.js.map +1 -0
  15. package/dist/api/unread_count.d.ts +82 -0
  16. package/dist/api/unread_count.d.ts.map +1 -0
  17. package/dist/api/unread_count.js +111 -0
  18. package/dist/api/unread_count.js.map +1 -0
  19. package/dist/components/hazo_chat/hazo_chat.d.ts +28 -0
  20. package/dist/components/hazo_chat/hazo_chat.d.ts.map +1 -0
  21. package/dist/components/hazo_chat/hazo_chat.js +230 -0
  22. package/dist/components/hazo_chat/hazo_chat.js.map +1 -0
  23. package/dist/components/hazo_chat/hazo_chat_attachment_preview.d.ts +17 -0
  24. package/dist/components/hazo_chat/hazo_chat_attachment_preview.d.ts.map +1 -0
  25. package/dist/components/hazo_chat/hazo_chat_attachment_preview.js +60 -0
  26. package/dist/components/hazo_chat/hazo_chat_attachment_preview.js.map +1 -0
  27. package/dist/components/hazo_chat/hazo_chat_context.d.ts +46 -0
  28. package/dist/components/hazo_chat/hazo_chat_context.d.ts.map +1 -0
  29. package/dist/components/hazo_chat/hazo_chat_context.js +277 -0
  30. package/dist/components/hazo_chat/hazo_chat_context.js.map +1 -0
  31. package/dist/components/hazo_chat/hazo_chat_document_viewer.d.ts +15 -0
  32. package/dist/components/hazo_chat/hazo_chat_document_viewer.d.ts.map +1 -0
  33. package/dist/components/hazo_chat/hazo_chat_document_viewer.js +140 -0
  34. package/dist/components/hazo_chat/hazo_chat_document_viewer.js.map +1 -0
  35. package/dist/components/hazo_chat/hazo_chat_header.d.ts +16 -0
  36. package/dist/components/hazo_chat/hazo_chat_header.d.ts.map +1 -0
  37. package/dist/components/hazo_chat/hazo_chat_header.js +45 -0
  38. package/dist/components/hazo_chat/hazo_chat_header.js.map +1 -0
  39. package/dist/components/hazo_chat/hazo_chat_input.d.ts +16 -0
  40. package/dist/components/hazo_chat/hazo_chat_input.d.ts.map +1 -0
  41. package/dist/components/hazo_chat/hazo_chat_input.js +75 -0
  42. package/dist/components/hazo_chat/hazo_chat_input.js.map +1 -0
  43. package/dist/components/hazo_chat/hazo_chat_messages.d.ts +18 -0
  44. package/dist/components/hazo_chat/hazo_chat_messages.d.ts.map +1 -0
  45. package/dist/components/hazo_chat/hazo_chat_messages.js +255 -0
  46. package/dist/components/hazo_chat/hazo_chat_messages.js.map +1 -0
  47. package/dist/components/hazo_chat/hazo_chat_reference_list.d.ts +16 -0
  48. package/dist/components/hazo_chat/hazo_chat_reference_list.d.ts.map +1 -0
  49. package/dist/components/hazo_chat/hazo_chat_reference_list.js +59 -0
  50. package/dist/components/hazo_chat/hazo_chat_reference_list.js.map +1 -0
  51. package/dist/components/hazo_chat/hazo_chat_sidebar.d.ts +18 -0
  52. package/dist/components/hazo_chat/hazo_chat_sidebar.d.ts.map +1 -0
  53. package/dist/components/hazo_chat/hazo_chat_sidebar.js +72 -0
  54. package/dist/components/hazo_chat/hazo_chat_sidebar.js.map +1 -0
  55. package/dist/components/hazo_chat/index.d.ts +16 -0
  56. package/dist/components/hazo_chat/index.d.ts.map +1 -0
  57. package/dist/components/hazo_chat/index.js +19 -0
  58. package/dist/components/hazo_chat/index.js.map +1 -0
  59. package/dist/components/index.d.ts +9 -0
  60. package/dist/components/index.d.ts.map +1 -0
  61. package/dist/components/index.js +11 -0
  62. package/dist/components/index.js.map +1 -0
  63. package/dist/components/ui/avatar.d.ts +13 -0
  64. package/dist/components/ui/avatar.d.ts.map +1 -0
  65. package/dist/components/ui/avatar.js +28 -0
  66. package/dist/components/ui/avatar.js.map +1 -0
  67. package/dist/components/ui/badge.d.ts +16 -0
  68. package/dist/components/ui/badge.d.ts.map +1 -0
  69. package/dist/components/ui/badge.js +36 -0
  70. package/dist/components/ui/badge.js.map +1 -0
  71. package/dist/components/ui/button.d.ts +18 -0
  72. package/dist/components/ui/button.d.ts.map +1 -0
  73. package/dist/components/ui/button.js +47 -0
  74. package/dist/components/ui/button.js.map +1 -0
  75. package/dist/components/ui/chat_bubble.d.ts +18 -0
  76. package/dist/components/ui/chat_bubble.d.ts.map +1 -0
  77. package/dist/components/ui/chat_bubble.js +130 -0
  78. package/dist/components/ui/chat_bubble.js.map +1 -0
  79. package/dist/components/ui/hover-card.d.ts +13 -0
  80. package/dist/components/ui/hover-card.d.ts.map +1 -0
  81. package/dist/components/ui/hover-card.js +17 -0
  82. package/dist/components/ui/hover-card.js.map +1 -0
  83. package/dist/components/ui/index.d.ts +19 -0
  84. package/dist/components/ui/index.d.ts.map +1 -0
  85. package/dist/components/ui/index.js +21 -0
  86. package/dist/components/ui/index.js.map +1 -0
  87. package/dist/components/ui/input.d.ts +11 -0
  88. package/dist/components/ui/input.d.ts.map +1 -0
  89. package/dist/components/ui/input.js +18 -0
  90. package/dist/components/ui/input.js.map +1 -0
  91. package/dist/components/ui/loading_skeleton.d.ts +19 -0
  92. package/dist/components/ui/loading_skeleton.d.ts.map +1 -0
  93. package/dist/components/ui/loading_skeleton.js +30 -0
  94. package/dist/components/ui/loading_skeleton.js.map +1 -0
  95. package/dist/components/ui/scroll-area.d.ts +12 -0
  96. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  97. package/dist/components/ui/scroll-area.js +25 -0
  98. package/dist/components/ui/scroll-area.js.map +1 -0
  99. package/dist/components/ui/separator.d.ts +11 -0
  100. package/dist/components/ui/separator.d.ts.map +1 -0
  101. package/dist/components/ui/separator.js +18 -0
  102. package/dist/components/ui/separator.js.map +1 -0
  103. package/dist/components/ui/skeleton.d.ts +9 -0
  104. package/dist/components/ui/skeleton.d.ts.map +1 -0
  105. package/dist/components/ui/skeleton.js +16 -0
  106. package/dist/components/ui/skeleton.js.map +1 -0
  107. package/dist/components/ui/textarea.d.ts +11 -0
  108. package/dist/components/ui/textarea.d.ts.map +1 -0
  109. package/dist/components/ui/textarea.js +18 -0
  110. package/dist/components/ui/textarea.js.map +1 -0
  111. package/dist/components/ui/tooltip.d.ts +14 -0
  112. package/dist/components/ui/tooltip.d.ts.map +1 -0
  113. package/dist/components/ui/tooltip.js +30 -0
  114. package/dist/components/ui/tooltip.js.map +1 -0
  115. package/dist/hooks/index.d.ts +10 -0
  116. package/dist/hooks/index.d.ts.map +1 -0
  117. package/dist/hooks/index.js +10 -0
  118. package/dist/hooks/index.js.map +1 -0
  119. package/dist/hooks/use_chat_messages.d.ts +38 -0
  120. package/dist/hooks/use_chat_messages.d.ts.map +1 -0
  121. package/dist/hooks/use_chat_messages.js +584 -0
  122. package/dist/hooks/use_chat_messages.js.map +1 -0
  123. package/dist/hooks/use_chat_references.d.ts +17 -0
  124. package/dist/hooks/use_chat_references.d.ts.map +1 -0
  125. package/dist/hooks/use_chat_references.js +133 -0
  126. package/dist/hooks/use_chat_references.js.map +1 -0
  127. package/dist/hooks/use_file_upload.d.ts +26 -0
  128. package/dist/hooks/use_file_upload.d.ts.map +1 -0
  129. package/dist/hooks/use_file_upload.js +216 -0
  130. package/dist/hooks/use_file_upload.js.map +1 -0
  131. package/dist/index.d.ts +13 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +17 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/lib/config.d.ts +41 -0
  136. package/dist/lib/config.d.ts.map +1 -0
  137. package/dist/lib/config.js +93 -0
  138. package/dist/lib/config.js.map +1 -0
  139. package/dist/lib/constants.d.ts +41 -0
  140. package/dist/lib/constants.d.ts.map +1 -0
  141. package/dist/lib/constants.js +72 -0
  142. package/dist/lib/constants.js.map +1 -0
  143. package/dist/lib/index.d.ts +9 -0
  144. package/dist/lib/index.d.ts.map +1 -0
  145. package/dist/lib/index.js +9 -0
  146. package/dist/lib/index.js.map +1 -0
  147. package/dist/lib/utils.d.ts +17 -0
  148. package/dist/lib/utils.d.ts.map +1 -0
  149. package/dist/lib/utils.js +20 -0
  150. package/dist/lib/utils.js.map +1 -0
  151. package/dist/types/index.d.ts +572 -0
  152. package/dist/types/index.d.ts.map +1 -0
  153. package/dist/types/index.js +11 -0
  154. package/dist/types/index.js.map +1 -0
  155. package/package.json +2 -6
@@ -0,0 +1,584 @@
1
+ /**
2
+ * useChatMessages Hook
3
+ *
4
+ * Manages chat messages with:
5
+ * - Cursor-based pagination (infinite scroll)
6
+ * - Polling for new messages with configurable interval
7
+ * - Optimistic updates for sent messages
8
+ * - Soft delete functionality
9
+ * - Exponential backoff on errors
10
+ * - Abstracted transport layer for future WebSocket/SSE support
11
+ *
12
+ * Uses fetch() to call API endpoints instead of direct database access.
13
+ * This allows the hook to work in client components without Node.js dependencies.
14
+ */
15
+ 'use client';
16
+ import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
17
+ import { DEFAULT_REALTIME_MODE, DEFAULT_POLLING_INTERVAL, DEFAULT_MESSAGES_PER_PAGE, MAX_RETRY_ATTEMPTS, } from '../lib/constants.js';
18
+ // ============================================================================
19
+ // Constants
20
+ // ============================================================================
21
+ /** Maximum entries in the user profile cache */
22
+ const PROFILE_CACHE_MAX_SIZE = 200;
23
+ /** Cache TTL in milliseconds (30 minutes) */
24
+ const PROFILE_CACHE_TTL = 1000 * 60 * 30;
25
+ /** Maximum polling delay cap in milliseconds */
26
+ const MAX_POLLING_DELAY = 30000;
27
+ // ============================================================================
28
+ // Helper: Generate unique ID for optimistic messages
29
+ // ============================================================================
30
+ function generateOptimisticId() {
31
+ return `optimistic-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
32
+ }
33
+ // ============================================================================
34
+ // Hook Implementation
35
+ // ============================================================================
36
+ export function useChatMessages({ chat_group_id, logger, reference_id = '', reference_type = 'chat', api_base_url = '/api/hazo_chat', realtime_mode = DEFAULT_REALTIME_MODE, polling_interval = DEFAULT_POLLING_INTERVAL, messages_per_page = DEFAULT_MESSAGES_PER_PAGE, }) {
37
+ // -------------------------------------------------------------------------
38
+ // State
39
+ // -------------------------------------------------------------------------
40
+ const [messages, set_messages] = useState([]);
41
+ const [is_loading, set_is_loading] = useState(true);
42
+ const [is_loading_more, set_is_loading_more] = useState(false);
43
+ const [has_more, set_has_more] = useState(true);
44
+ const [error, set_error] = useState(null);
45
+ const [polling_status, set_polling_status] = useState('connected');
46
+ const [current_user_id, set_current_user_id] = useState(null);
47
+ // -------------------------------------------------------------------------
48
+ // Refs (stable across renders)
49
+ // -------------------------------------------------------------------------
50
+ const cursor_ref = useRef(null);
51
+ const retry_count_ref = useRef(0);
52
+ const user_profiles_cache_ref = useRef(new Map());
53
+ const polling_timer_ref = useRef(null);
54
+ const is_mounted_ref = useRef(true);
55
+ const is_polling_ref = useRef(false);
56
+ // -------------------------------------------------------------------------
57
+ // Memoized config to prevent effect re-runs
58
+ // -------------------------------------------------------------------------
59
+ const config = useMemo(() => ({
60
+ chat_group_id,
61
+ reference_id,
62
+ reference_type,
63
+ api_base_url,
64
+ realtime_mode,
65
+ polling_interval,
66
+ messages_per_page,
67
+ }), [chat_group_id, reference_id, reference_type, api_base_url, realtime_mode, polling_interval, messages_per_page]);
68
+ // -------------------------------------------------------------------------
69
+ // Cleanup on unmount
70
+ // -------------------------------------------------------------------------
71
+ useEffect(() => {
72
+ is_mounted_ref.current = true;
73
+ return () => {
74
+ is_mounted_ref.current = false;
75
+ if (polling_timer_ref.current) {
76
+ clearTimeout(polling_timer_ref.current);
77
+ polling_timer_ref.current = null;
78
+ }
79
+ };
80
+ }, []);
81
+ // -------------------------------------------------------------------------
82
+ // User profile cache with TTL and eviction
83
+ // -------------------------------------------------------------------------
84
+ const get_cached_profile = useCallback((user_id) => {
85
+ const entry = user_profiles_cache_ref.current.get(user_id);
86
+ if (!entry)
87
+ return null;
88
+ // Check TTL
89
+ if (Date.now() - entry.timestamp > PROFILE_CACHE_TTL) {
90
+ user_profiles_cache_ref.current.delete(user_id);
91
+ return null;
92
+ }
93
+ return entry.value;
94
+ }, []);
95
+ const set_cached_profile = useCallback((profile) => {
96
+ // Evict oldest entries if cache is too large
97
+ if (user_profiles_cache_ref.current.size >= PROFILE_CACHE_MAX_SIZE) {
98
+ // Find and remove oldest entry
99
+ let oldest_key = null;
100
+ let oldest_timestamp = Infinity;
101
+ user_profiles_cache_ref.current.forEach((entry, key) => {
102
+ if (entry.timestamp < oldest_timestamp) {
103
+ oldest_timestamp = entry.timestamp;
104
+ oldest_key = key;
105
+ }
106
+ });
107
+ if (oldest_key) {
108
+ user_profiles_cache_ref.current.delete(oldest_key);
109
+ }
110
+ }
111
+ user_profiles_cache_ref.current.set(profile.id, {
112
+ value: profile,
113
+ timestamp: Date.now(),
114
+ });
115
+ }, []);
116
+ // -------------------------------------------------------------------------
117
+ // Fetch user profiles via API (with cache)
118
+ // -------------------------------------------------------------------------
119
+ const fetch_user_profiles = useCallback(async (user_ids) => {
120
+ const result = new Map();
121
+ const uncached_ids = [];
122
+ // Check cache first
123
+ user_ids.forEach((id) => {
124
+ const cached = get_cached_profile(id);
125
+ if (cached) {
126
+ result.set(id, cached);
127
+ }
128
+ else {
129
+ uncached_ids.push(id);
130
+ }
131
+ });
132
+ // Fetch uncached profiles
133
+ if (uncached_ids.length > 0) {
134
+ try {
135
+ const response = await fetch('/api/hazo_auth/profiles', {
136
+ method: 'POST',
137
+ headers: { 'Content-Type': 'application/json' },
138
+ body: JSON.stringify({ user_ids: uncached_ids }),
139
+ credentials: 'include',
140
+ });
141
+ if (response.ok) {
142
+ const data = await response.json();
143
+ if (data.success && data.profiles) {
144
+ data.profiles.forEach((profile) => {
145
+ set_cached_profile(profile);
146
+ result.set(profile.id, profile);
147
+ });
148
+ }
149
+ }
150
+ }
151
+ catch (err) {
152
+ logger.error('[useChatMessages] Failed to fetch user profiles:', { error: err });
153
+ }
154
+ }
155
+ return result;
156
+ }, [get_cached_profile, set_cached_profile]);
157
+ // -------------------------------------------------------------------------
158
+ // Transform DB messages to ChatMessage
159
+ // -------------------------------------------------------------------------
160
+ const transform_messages = useCallback(async (db_messages, user_id) => {
161
+ // Collect all unique sender IDs (no longer need receiver since it's group-based)
162
+ const user_ids = new Set();
163
+ db_messages.forEach((msg) => {
164
+ user_ids.add(msg.sender_user_id);
165
+ });
166
+ // Fetch profiles
167
+ const profiles = await fetch_user_profiles(Array.from(user_ids));
168
+ // Transform messages
169
+ return db_messages.map((msg) => ({
170
+ ...msg,
171
+ sender_profile: profiles.get(msg.sender_user_id),
172
+ is_sender: msg.sender_user_id === user_id,
173
+ send_status: 'sent',
174
+ }));
175
+ }, [fetch_user_profiles]);
176
+ // -------------------------------------------------------------------------
177
+ // Calculate polling delay with exponential backoff
178
+ // -------------------------------------------------------------------------
179
+ const get_poll_delay = useCallback(() => {
180
+ if (retry_count_ref.current === 0) {
181
+ return config.polling_interval;
182
+ }
183
+ // Exponential backoff: interval * 2^retryCount, capped at MAX_POLLING_DELAY
184
+ const delay = config.polling_interval * Math.pow(2, retry_count_ref.current);
185
+ return Math.min(delay, MAX_POLLING_DELAY);
186
+ }, [config.polling_interval]);
187
+ // -------------------------------------------------------------------------
188
+ // Fetch messages via API with optional pagination
189
+ // -------------------------------------------------------------------------
190
+ const fetch_messages_from_api = useCallback(async (options) => {
191
+ if (!config.chat_group_id) {
192
+ return { messages: [], user_id: null, has_more: false, next_cursor: null };
193
+ }
194
+ try {
195
+ const params = new URLSearchParams({
196
+ chat_group_id: config.chat_group_id,
197
+ limit: String(options?.limit || config.messages_per_page),
198
+ });
199
+ if (config.reference_id) {
200
+ params.set('reference_id', config.reference_id);
201
+ }
202
+ if (config.reference_type) {
203
+ params.set('reference_type', config.reference_type);
204
+ }
205
+ if (options?.cursor) {
206
+ params.set('cursor', options.cursor);
207
+ params.set('direction', options.direction || 'older');
208
+ }
209
+ const response = await fetch(`${config.api_base_url}/messages?${params.toString()}`, {
210
+ credentials: 'include',
211
+ });
212
+ if (!response.ok) {
213
+ throw new Error(`HTTP ${response.status}`);
214
+ }
215
+ const data = await response.json();
216
+ if (data.success) {
217
+ return {
218
+ messages: data.messages || [],
219
+ user_id: data.current_user_id || null,
220
+ has_more: data.pagination?.has_more ?? false,
221
+ next_cursor: data.pagination?.next_cursor ?? null,
222
+ };
223
+ }
224
+ else {
225
+ throw new Error(data.error || 'Failed to fetch messages');
226
+ }
227
+ }
228
+ catch (err) {
229
+ logger.error('[useChatMessages] Fetch error:', { error: err });
230
+ throw err;
231
+ }
232
+ }, [config]);
233
+ // -------------------------------------------------------------------------
234
+ // Initial load
235
+ // -------------------------------------------------------------------------
236
+ const load_initial = useCallback(async () => {
237
+ if (!config.chat_group_id) {
238
+ set_is_loading(false);
239
+ return;
240
+ }
241
+ set_is_loading(true);
242
+ set_error(null);
243
+ try {
244
+ const result = await fetch_messages_from_api();
245
+ if (result.user_id && is_mounted_ref.current) {
246
+ set_current_user_id(result.user_id);
247
+ }
248
+ if (is_mounted_ref.current) {
249
+ const transformed = result.user_id
250
+ ? await transform_messages(result.messages, result.user_id)
251
+ : result.messages.map((msg) => ({
252
+ ...msg,
253
+ is_sender: false,
254
+ send_status: 'sent',
255
+ }));
256
+ // Sort messages in ascending order (oldest first, newest last)
257
+ const sorted = transformed.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
258
+ set_messages(sorted);
259
+ set_has_more(result.has_more);
260
+ cursor_ref.current = result.next_cursor;
261
+ retry_count_ref.current = 0;
262
+ set_polling_status('connected');
263
+ }
264
+ }
265
+ catch (err) {
266
+ if (is_mounted_ref.current) {
267
+ set_error('Failed to load messages');
268
+ set_polling_status('error');
269
+ }
270
+ }
271
+ finally {
272
+ if (is_mounted_ref.current) {
273
+ set_is_loading(false);
274
+ }
275
+ }
276
+ }, [config.chat_group_id, fetch_messages_from_api, transform_messages]);
277
+ // -------------------------------------------------------------------------
278
+ // Load more (pagination)
279
+ // -------------------------------------------------------------------------
280
+ const load_more = useCallback(async () => {
281
+ if (!current_user_id || !has_more || is_loading_more || !cursor_ref.current) {
282
+ return;
283
+ }
284
+ set_is_loading_more(true);
285
+ try {
286
+ const result = await fetch_messages_from_api({
287
+ cursor: cursor_ref.current,
288
+ direction: 'older',
289
+ });
290
+ const transformed = await transform_messages(result.messages, current_user_id);
291
+ if (is_mounted_ref.current) {
292
+ set_messages((prev) => {
293
+ // Prepend older messages and sort
294
+ const combined = [...transformed, ...prev];
295
+ return combined.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
296
+ });
297
+ set_has_more(result.has_more);
298
+ // Update cursor to oldest message for next load_more
299
+ if (result.messages.length > 0) {
300
+ cursor_ref.current = result.messages[0].created_at;
301
+ }
302
+ }
303
+ }
304
+ catch (err) {
305
+ logger.error('[useChatMessages] Load more error:', { error: err });
306
+ }
307
+ finally {
308
+ if (is_mounted_ref.current) {
309
+ set_is_loading_more(false);
310
+ }
311
+ }
312
+ }, [current_user_id, has_more, is_loading_more, fetch_messages_from_api, transform_messages]);
313
+ // -------------------------------------------------------------------------
314
+ // Poll for new messages (uses setTimeout for proper backoff)
315
+ // -------------------------------------------------------------------------
316
+ const schedule_next_poll = useCallback(() => {
317
+ if (!is_mounted_ref.current || config.realtime_mode !== 'polling' || !config.chat_group_id) {
318
+ return;
319
+ }
320
+ const delay = get_poll_delay();
321
+ polling_timer_ref.current = setTimeout(async () => {
322
+ if (!is_mounted_ref.current || is_polling_ref.current) {
323
+ return;
324
+ }
325
+ is_polling_ref.current = true;
326
+ try {
327
+ // Fetch only newer messages since our latest
328
+ const latest_message = messages[messages.length - 1];
329
+ const result = await fetch_messages_from_api(latest_message
330
+ ? { cursor: latest_message.created_at, direction: 'newer', limit: 50 }
331
+ : undefined);
332
+ if (result.messages.length > 0 && is_mounted_ref.current && current_user_id) {
333
+ const transformed = await transform_messages(result.messages, current_user_id);
334
+ set_messages((prev) => {
335
+ // Merge new messages, avoiding duplicates
336
+ const existing_ids = new Set(prev.map((m) => m.id));
337
+ const new_messages = transformed.filter((m) => !existing_ids.has(m.id));
338
+ if (new_messages.length > 0) {
339
+ const combined = [...prev, ...new_messages];
340
+ return combined.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
341
+ }
342
+ return prev;
343
+ });
344
+ }
345
+ // Reset retry count on success
346
+ retry_count_ref.current = 0;
347
+ if (is_mounted_ref.current) {
348
+ set_polling_status('connected');
349
+ }
350
+ }
351
+ catch (err) {
352
+ logger.error('[useChatMessages] Polling error:', { error: err });
353
+ retry_count_ref.current += 1;
354
+ if (is_mounted_ref.current) {
355
+ if (retry_count_ref.current >= MAX_RETRY_ATTEMPTS) {
356
+ set_polling_status('error');
357
+ }
358
+ else {
359
+ set_polling_status('reconnecting');
360
+ }
361
+ }
362
+ }
363
+ finally {
364
+ is_polling_ref.current = false;
365
+ // Schedule next poll with updated delay (backoff applied via get_poll_delay)
366
+ if (is_mounted_ref.current && config.realtime_mode === 'polling') {
367
+ schedule_next_poll();
368
+ }
369
+ }
370
+ }, delay);
371
+ }, [config.realtime_mode, config.chat_group_id, get_poll_delay, fetch_messages_from_api, transform_messages, messages, current_user_id]);
372
+ // -------------------------------------------------------------------------
373
+ // Start/stop polling based on realtime_mode
374
+ // -------------------------------------------------------------------------
375
+ useEffect(() => {
376
+ // Clear any existing timer
377
+ if (polling_timer_ref.current) {
378
+ clearTimeout(polling_timer_ref.current);
379
+ polling_timer_ref.current = null;
380
+ }
381
+ // Only start polling if mode is 'polling' and we have a chat group
382
+ if (config.realtime_mode === 'polling' && config.chat_group_id && current_user_id) {
383
+ schedule_next_poll();
384
+ }
385
+ else if (config.realtime_mode === 'manual') {
386
+ set_polling_status('connected');
387
+ }
388
+ return () => {
389
+ if (polling_timer_ref.current) {
390
+ clearTimeout(polling_timer_ref.current);
391
+ polling_timer_ref.current = null;
392
+ }
393
+ };
394
+ }, [config.realtime_mode, config.chat_group_id, current_user_id, schedule_next_poll]);
395
+ // -------------------------------------------------------------------------
396
+ // Initial load effect
397
+ // -------------------------------------------------------------------------
398
+ useEffect(() => {
399
+ load_initial();
400
+ }, [load_initial]);
401
+ // -------------------------------------------------------------------------
402
+ // Send message via API
403
+ // -------------------------------------------------------------------------
404
+ const send_message = useCallback(async (payload) => {
405
+ if (!current_user_id) {
406
+ set_error('Not authenticated');
407
+ return false;
408
+ }
409
+ // Create optimistic message with unique ID
410
+ const optimistic_id = generateOptimisticId();
411
+ const sender_profile = get_cached_profile(current_user_id);
412
+ const optimistic_message = {
413
+ id: optimistic_id,
414
+ reference_id: payload.reference_id,
415
+ reference_type: payload.reference_type,
416
+ sender_user_id: current_user_id,
417
+ chat_group_id: payload.chat_group_id,
418
+ message_text: payload.message_text,
419
+ reference_list: payload.reference_list || null,
420
+ read_at: null,
421
+ deleted_at: null,
422
+ created_at: new Date().toISOString(),
423
+ changed_at: new Date().toISOString(),
424
+ sender_profile: sender_profile || undefined,
425
+ is_sender: true,
426
+ send_status: 'sending',
427
+ };
428
+ // Add optimistic message to state
429
+ set_messages((prev) => {
430
+ const updated = [...prev, optimistic_message];
431
+ return updated.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
432
+ });
433
+ try {
434
+ const response = await fetch(`${config.api_base_url}/messages`, {
435
+ method: 'POST',
436
+ headers: { 'Content-Type': 'application/json' },
437
+ credentials: 'include',
438
+ body: JSON.stringify({
439
+ chat_group_id: payload.chat_group_id,
440
+ message_text: payload.message_text,
441
+ reference_id: payload.reference_id,
442
+ reference_type: payload.reference_type,
443
+ }),
444
+ });
445
+ const data = await response.json();
446
+ if (data.success && data.message && is_mounted_ref.current) {
447
+ // Replace optimistic message with real one
448
+ const real_message = {
449
+ ...data.message,
450
+ reference_list: data.message.reference_list ?? null,
451
+ read_at: data.message.read_at ?? null,
452
+ deleted_at: data.message.deleted_at ?? null,
453
+ changed_at: data.message.changed_at ?? data.message.created_at,
454
+ sender_profile: sender_profile || undefined,
455
+ is_sender: true,
456
+ send_status: 'sent',
457
+ };
458
+ set_messages((prev) => {
459
+ // Check if real message already exists (from polling)
460
+ const real_message_exists = prev.some((msg) => msg.id === real_message.id);
461
+ if (real_message_exists) {
462
+ // Real message already exists from polling, just remove optimistic one
463
+ return prev.filter((msg) => msg.id !== optimistic_id);
464
+ }
465
+ else {
466
+ // Replace optimistic message with real one
467
+ const replaced = prev.map((msg) => msg.id === optimistic_id ? real_message : msg);
468
+ return replaced.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
469
+ }
470
+ });
471
+ return true;
472
+ }
473
+ else {
474
+ throw new Error(data.error || 'Failed to send message');
475
+ }
476
+ }
477
+ catch (err) {
478
+ logger.error('[useChatMessages] Send error:', { error: err });
479
+ // Mark optimistic message as failed
480
+ if (is_mounted_ref.current) {
481
+ set_messages((prev) => prev.map((msg) => msg.id === optimistic_id ? { ...msg, send_status: 'failed' } : msg));
482
+ }
483
+ return false;
484
+ }
485
+ }, [current_user_id, config.api_base_url, get_cached_profile]);
486
+ // -------------------------------------------------------------------------
487
+ // Delete message (soft delete) via API
488
+ // -------------------------------------------------------------------------
489
+ const delete_message = useCallback(async (message_id) => {
490
+ if (!current_user_id) {
491
+ return false;
492
+ }
493
+ // Find the message to verify ownership
494
+ const message = messages.find((m) => m.id === message_id);
495
+ if (!message || message.sender_user_id !== current_user_id) {
496
+ set_error('Cannot delete this message');
497
+ return false;
498
+ }
499
+ // Store original values for rollback
500
+ const original_deleted_at = message.deleted_at;
501
+ const original_message_text = message.message_text;
502
+ // Optimistic update
503
+ set_messages((prev) => prev.map((msg) => msg.id === message_id
504
+ ? { ...msg, deleted_at: new Date().toISOString(), message_text: null }
505
+ : msg));
506
+ try {
507
+ const response = await fetch(`${config.api_base_url}/messages/${message_id}`, {
508
+ method: 'DELETE',
509
+ credentials: 'include',
510
+ });
511
+ if (!response.ok) {
512
+ throw new Error('Failed to delete message');
513
+ }
514
+ return true;
515
+ }
516
+ catch (err) {
517
+ logger.error('[useChatMessages] Delete error:', { error: err });
518
+ // Rollback on error
519
+ if (is_mounted_ref.current) {
520
+ set_messages((prev) => prev.map((msg) => msg.id === message_id
521
+ ? { ...msg, deleted_at: original_deleted_at, message_text: original_message_text }
522
+ : msg));
523
+ }
524
+ return false;
525
+ }
526
+ }, [current_user_id, messages, config.api_base_url]);
527
+ // -------------------------------------------------------------------------
528
+ // Mark as read via API
529
+ // -------------------------------------------------------------------------
530
+ const mark_as_read = useCallback(async (message_id) => {
531
+ if (!current_user_id) {
532
+ return;
533
+ }
534
+ const message = messages.find((m) => m.id === message_id);
535
+ if (!message || message.read_at || message.sender_user_id === current_user_id) {
536
+ return;
537
+ }
538
+ try {
539
+ const response = await fetch(`${config.api_base_url}/messages/${message_id}/read`, {
540
+ method: 'PATCH',
541
+ credentials: 'include',
542
+ });
543
+ if (!response.ok) {
544
+ logger.error('[useChatMessages] Mark as read failed:', { status: response.status });
545
+ return;
546
+ }
547
+ const data = await response.json();
548
+ if (data.success && is_mounted_ref.current) {
549
+ set_messages((prev) => prev.map((msg) => msg.id === message_id
550
+ ? { ...msg, read_at: data.message?.read_at || new Date().toISOString() }
551
+ : msg));
552
+ }
553
+ }
554
+ catch (err) {
555
+ logger.error('[useChatMessages] Mark as read error:', { error: err });
556
+ }
557
+ }, [current_user_id, messages, config.api_base_url, logger]);
558
+ // -------------------------------------------------------------------------
559
+ // Refresh
560
+ // -------------------------------------------------------------------------
561
+ const refresh = useCallback(() => {
562
+ cursor_ref.current = null;
563
+ retry_count_ref.current = 0;
564
+ set_messages([]);
565
+ load_initial();
566
+ }, [load_initial]);
567
+ // -------------------------------------------------------------------------
568
+ // Return
569
+ // -------------------------------------------------------------------------
570
+ return {
571
+ messages,
572
+ is_loading,
573
+ is_loading_more,
574
+ has_more,
575
+ error,
576
+ polling_status,
577
+ load_more,
578
+ send_message,
579
+ delete_message,
580
+ mark_as_read,
581
+ refresh
582
+ };
583
+ }
584
+ //# sourceMappingURL=use_chat_messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_chat_messages.js","sourceRoot":"","sources":["../../src/hooks/use_chat_messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * useChatReferences Hook
3
+ *
4
+ * Manages chat references with:
5
+ * - Aggregating references from messages and props
6
+ * - Selection state management
7
+ * - Finding source message for a reference
8
+ */
9
+ import type { ChatReferenceItem, ChatMessage, ReferenceItem, UseChatReferencesReturn } from '../types/index.js';
10
+ interface UseChatReferencesParams {
11
+ messages: ChatMessage[];
12
+ initial_references?: ReferenceItem[];
13
+ on_selection_change?: (reference: ChatReferenceItem | null) => void;
14
+ }
15
+ export declare function useChatReferences({ messages, initial_references, on_selection_change }: UseChatReferencesParams): UseChatReferencesReturn;
16
+ export {};
17
+ //# sourceMappingURL=use_chat_references.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_chat_references.d.ts","sourceRoot":"","sources":["../../src/hooks/use_chat_references.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAM3B,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,kBAAkB,CAAC,EAAE,aAAa,EAAE,CAAC;IACrC,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI,KAAK,IAAI,CAAC;CACrE;AAMD,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,kBAAuB,EACvB,mBAAmB,EACpB,EAAE,uBAAuB,GAAG,uBAAuB,CA6InD"}