@thrillee/aegischat 0.1.9 → 0.1.11

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.js CHANGED
@@ -75,7 +75,7 @@ var chatApi = {
75
75
  * Connect to chat session
76
76
  */
77
77
  async connect(params, signal) {
78
- return fetchWithAuth("/api/v1/chat/connect", {
78
+ return fetchWithAuth("/chat/connect", {
79
79
  method: "POST",
80
80
  body: JSON.stringify(params),
81
81
  signal
@@ -85,7 +85,7 @@ var chatApi = {
85
85
  * Refresh access token
86
86
  */
87
87
  async refreshToken(refreshToken, signal) {
88
- return fetchWithAuth("/api/v1/chat/refresh", {
88
+ return fetchWithAuth("/chat/refresh", {
89
89
  method: "POST",
90
90
  body: JSON.stringify({ refresh_token: refreshToken }),
91
91
  signal
@@ -101,19 +101,19 @@ var channelsApi = {
101
101
  if (options.type) params.append("type", options.type);
102
102
  if (options.limit) params.append("limit", String(options.limit));
103
103
  const query = params.toString() ? `?${params.toString()}` : "";
104
- return fetchWithAuth(`/api/v1/channels${query}`, { signal });
104
+ return fetchWithAuth(`/channels${query}`, { signal });
105
105
  },
106
106
  /**
107
107
  * Get channel by ID
108
108
  */
109
109
  async get(channelId, signal) {
110
- return fetchWithAuth(`/api/v1/channels/${channelId}`, { signal });
110
+ return fetchWithAuth(`/channels/${channelId}`, { signal });
111
111
  },
112
112
  /**
113
113
  * Get or create DM channel
114
114
  */
115
115
  async getOrCreateDM(userId, signal) {
116
- return fetchWithAuth("/api/v1/channels/dm", {
116
+ return fetchWithAuth("/channels/dm", {
117
117
  method: "POST",
118
118
  body: JSON.stringify({ user_id: userId }),
119
119
  signal
@@ -142,7 +142,7 @@ var channelsApi = {
142
142
  * Get channel members
143
143
  */
144
144
  async getMembers(channelId, signal) {
145
- return fetchWithAuth(`/api/v1/channels/${channelId}/members`, { signal });
145
+ return fetchWithAuth(`/channels/${channelId}/members`, { signal });
146
146
  },
147
147
  /**
148
148
  * Update channel
@@ -164,13 +164,15 @@ var messagesApi = {
164
164
  if (options.limit) params.append("limit", String(options.limit));
165
165
  if (options.before) params.append("before", options.before);
166
166
  const query = params.toString() ? `?${params.toString()}` : "";
167
- return fetchWithAuth(`/api/v1/channels/${channelId}/messages${query}`, { signal });
167
+ return fetchWithAuth(`/channels/${channelId}/messages${query}`, {
168
+ signal
169
+ });
168
170
  },
169
171
  /**
170
172
  * Send a message
171
173
  */
172
174
  async send(channelId, data, signal) {
173
- return fetchWithAuth(`/api/v1/channels/${channelId}/messages`, {
175
+ return fetchWithAuth(`/channels/${channelId}/messages`, {
174
176
  method: "POST",
175
177
  body: JSON.stringify(data),
176
178
  signal
@@ -180,7 +182,7 @@ var messagesApi = {
180
182
  * Update a message
181
183
  */
182
184
  async update(channelId, messageId, data, signal) {
183
- return fetchWithAuth(`/api/v1/channels/${channelId}/messages/${messageId}`, {
185
+ return fetchWithAuth(`/channels/${channelId}/messages/${messageId}`, {
184
186
  method: "PATCH",
185
187
  body: JSON.stringify(data),
186
188
  signal
@@ -190,7 +192,7 @@ var messagesApi = {
190
192
  * Delete a message
191
193
  */
192
194
  async delete(channelId, messageId, signal) {
193
- return fetchWithAuth(`/api/v1/channels/${channelId}/messages/${messageId}`, {
195
+ return fetchWithAuth(`/channels/${channelId}/messages/${messageId}`, {
194
196
  method: "DELETE",
195
197
  signal
196
198
  });
@@ -199,7 +201,7 @@ var messagesApi = {
199
201
  * Mark messages as delivered
200
202
  */
201
203
  async markDelivered(channelId, signal) {
202
- return fetchWithAuth(`/api/v1/channels/${channelId}/messages/delivered`, {
204
+ return fetchWithAuth(`/channels/${channelId}/messages/delivered`, {
203
205
  method: "POST",
204
206
  signal
205
207
  });
@@ -208,7 +210,7 @@ var messagesApi = {
208
210
  * Mark messages as read
209
211
  */
210
212
  async markRead(channelId, signal) {
211
- return fetchWithAuth(`/api/v1/channels/${channelId}/messages/read`, {
213
+ return fetchWithAuth(`/channels/${channelId}/messages/read`, {
212
214
  method: "POST",
213
215
  signal
214
216
  });
@@ -219,18 +221,21 @@ var reactionsApi = {
219
221
  * Add reaction to a message
220
222
  */
221
223
  async add(channelId, messageId, emoji, signal) {
222
- return fetchWithAuth(`/api/v1/channels/${channelId}/messages/${messageId}/reactions`, {
223
- method: "POST",
224
- body: JSON.stringify({ emoji }),
225
- signal
226
- });
224
+ return fetchWithAuth(
225
+ `/channels/${channelId}/messages/${messageId}/reactions`,
226
+ {
227
+ method: "POST",
228
+ body: JSON.stringify({ emoji }),
229
+ signal
230
+ }
231
+ );
227
232
  },
228
233
  /**
229
234
  * Remove reaction from a message
230
235
  */
231
236
  async remove(channelId, messageId, emoji, signal) {
232
237
  return fetchWithAuth(
233
- `/api/v1/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`,
238
+ `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`,
234
239
  { method: "DELETE", signal }
235
240
  );
236
241
  }
@@ -240,7 +245,7 @@ var filesApi = {
240
245
  * Get upload URL
241
246
  */
242
247
  async getUploadUrl(data, signal) {
243
- return fetchWithAuth("/api/v1/files/upload-url", {
248
+ return fetchWithAuth("/files/upload-url", {
244
249
  method: "POST",
245
250
  body: JSON.stringify(data),
246
251
  signal
@@ -250,7 +255,7 @@ var filesApi = {
250
255
  * Confirm file upload
251
256
  */
252
257
  async confirm(fileId, signal) {
253
- return fetchWithAuth("/api/v1/files", {
258
+ return fetchWithAuth("/files", {
254
259
  method: "POST",
255
260
  body: JSON.stringify({ file_id: fileId }),
256
261
  signal
@@ -260,7 +265,7 @@ var filesApi = {
260
265
  * Get download URL
261
266
  */
262
267
  async getDownloadUrl(fileId, signal) {
263
- return fetchWithAuth(`/api/v1/files/${fileId}/download`, { signal });
268
+ return fetchWithAuth(`/files/${fileId}/download`, { signal });
264
269
  }
265
270
  };
266
271
  var usersApi = {
@@ -268,13 +273,15 @@ var usersApi = {
268
273
  * Search users
269
274
  */
270
275
  async search(query, signal) {
271
- return fetchWithAuth(`/api/v1/users/search?q=${encodeURIComponent(query)}`, { signal });
276
+ return fetchWithAuth(`/users/search?q=${encodeURIComponent(query)}`, {
277
+ signal
278
+ });
272
279
  },
273
280
  /**
274
281
  * Get user by ID
275
282
  */
276
283
  async get(userId, signal) {
277
- return fetchWithAuth(`/api/v1/users/${userId}`, { signal });
284
+ return fetchWithAuth(`/users/${userId}`, { signal });
278
285
  }
279
286
  };
280
287
 
@@ -606,8 +613,8 @@ function useChat(options = {}) {
606
613
  if (!currentSession) return;
607
614
  setIsLoadingChannels(true);
608
615
  try {
609
- const response = await channelsApi.list({});
610
- setChannels(response.data.channels || []);
616
+ const response = await fetchFromComms("/channels");
617
+ setChannels(response.channels || []);
611
618
  } catch (error) {
612
619
  console.error("[AegisChat] Failed to fetch channels:", error);
613
620
  } finally {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/hooks/useChat.ts","../src/services/api.ts","../src/hooks/useAutoRead.ts","../src/hooks/useChannels.ts","../src/hooks/useMessages.ts","../src/hooks/useTypingIndicator.ts","../src/hooks/useReactions.ts","../src/hooks/useFileUpload.ts","../src/hooks/useMentions.ts"],"sourcesContent":["// ============================================================================\n// AegisChat React SDK - Main Entry Point\n// ============================================================================\n\nexport { useChat } from './hooks/useChat';\nexport type { UseChatOptions, UseChatReturn } from './hooks/useChat';\n\nexport { useAutoRead } from './hooks/useAutoRead';\nexport type { UseAutoReadOptions, UseAutoReadReturn } from './hooks/useAutoRead';\n\nexport { useChannels } from './hooks/useChannels';\nexport type { UseChannelsOptions, UseChannelsReturn } from './hooks/useChannels';\n\nexport { useMessages } from './hooks/useMessages';\nexport type { UseMessagesOptions, UseMessagesReturn } from './hooks/useMessages';\n\nexport { useTypingIndicator } from './hooks/useTypingIndicator';\nexport type { UseTypingIndicatorOptions } from './hooks/useTypingIndicator';\n\nexport { useReactions } from './hooks/useReactions';\nexport type { UseReactionsOptions } from './hooks/useReactions';\n\nexport { useFileUpload } from './hooks/useFileUpload';\nexport type { UseFileUploadOptions } from './hooks/useFileUpload';\n\nexport { useMentions } from './hooks/useMentions';\nexport type { UseMentionsOptions } from './hooks/useMentions';\n\nexport {\n chatApi,\n channelsApi,\n messagesApi,\n reactionsApi,\n filesApi,\n usersApi,\n configureApiClient,\n} from './services/api';\n\nexport type {\n AegisConfig,\n ChatSession,\n ChatConnectParams,\n UserSummary,\n UserStatus,\n Channel,\n ChannelListItem,\n ChannelType,\n Message,\n MessageSummary,\n MessageType,\n MessageStatus,\n MessageMetadata,\n FileAttachment,\n TypingUser,\n TypingEvent,\n ReactionSummary,\n ReactionEvent,\n UploadProgress,\n WebSocketMessage,\n WebSocketStatus,\n ApiResponse,\n ApiError,\n PaginationParams,\n PaginationMeta,\n PaginatedResponse,\n MessagesResponse,\n ChannelsResponse,\n} from './types';\n","// ============================================================================\n// AegisChat React SDK - useChat Hook\n// ============================================================================\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n chatApi,\n channelsApi,\n messagesApi,\n filesApi,\n configureApiClient,\n} from \"../services/api\";\nimport type {\n AegisConfig,\n ChatSession,\n ChannelListItem,\n Message,\n MessagesResponse,\n TypingUser,\n UserSummary,\n FileAttachment,\n UploadProgress,\n MessageSummary,\n} from \"../types\";\n\nconst TYPING_TIMEOUT = 3000;\nconst RECONNECT_INTERVAL = 3000;\nconst MAX_RECONNECT_ATTEMPTS = 5;\nconst MAX_RECONNECT_DELAY = 30000;\nconst PING_INTERVAL = 30000;\nconst SESSION_STORAGE_KEY = \"@aegischat/activeChannel\";\n\nexport interface UseChatOptions {\n config?: AegisConfig;\n role?: \"lawyer\" | \"client\";\n clientId?: string;\n\n initialSession?: ChatSession | null;\n autoConnect?: boolean;\n onMessage?: (message: Message) => void;\n onTyping?: (channelId: string, user: TypingUser) => void;\n onConnectionChange?: (connected: boolean) => void;\n}\n\nexport interface UseChatReturn {\n session: ChatSession | null;\n isConnected: boolean;\n isConnecting: boolean;\n channels: ChannelListItem[];\n messages: Message[];\n activeChannelId: string | null;\n typingUsers: TypingUser[];\n isLoadingChannels: boolean;\n isLoadingMessages: boolean;\n hasMoreMessages: boolean;\n uploadProgress: UploadProgress[];\n connect: () => Promise<void>;\n disconnect: () => void;\n selectChannel: (channelId: string) => void;\n sendMessage: (\n content: string,\n options?: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n },\n ) => Promise<void>;\n sendMessageWithFiles: (\n content: string,\n files: File[],\n options?: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n },\n ) => Promise<void>;\n uploadFile: (file: File) => Promise<FileAttachment | null>;\n loadMoreMessages: () => Promise<void>;\n startTyping: () => void;\n stopTyping: () => void;\n refreshChannels: () => Promise<void>;\n createDMWithUser: (userId: string) => Promise<string | null>;\n retryMessage: (tempId: string) => Promise<void>;\n deleteFailedMessage: (tempId: string) => void;\n markAsRead: (channelId: string) => Promise<void>;\n setup: (options: UseChatOptions) => void;\n}\n\nexport function useChat(options: Partial<UseChatOptions> = {}): UseChatReturn {\n const {\n config,\n role,\n clientId,\n initialSession,\n autoConnect = true,\n onMessage,\n onTyping,\n onConnectionChange,\n } = options;\n\n const [session, setSession] = useState<ChatSession | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [isConnecting, setIsConnecting] = useState(false);\n const [activeChannelId, setActiveChannelIdState] = useState<string | null>(\n null,\n );\n const [channels, setChannels] = useState<ChannelListItem[]>([]);\n const [messages, setMessages] = useState<Message[]>([]);\n const [typingUsers, setTypingUsers] = useState<Record<string, TypingUser[]>>(\n {},\n );\n const [isLoadingChannels, setIsLoadingChannels] = useState(false);\n const [isLoadingMessages, setIsLoadingMessages] = useState(false);\n const [hasMoreMessages, setHasMoreMessages] = useState(true);\n const [uploadProgress, setUploadProgress] = useState<UploadProgress[]>([]);\n\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectAttempts = useRef(0);\n const reconnectTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pingInterval = useRef<ReturnType<typeof setInterval> | null>(null);\n const typingTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isManualDisconnect = useRef(false);\n const oldestMessageId = useRef<string | null>(null);\n const activeChannelIdRef = useRef<string | null>(null);\n const sessionRef = useRef<ChatSession | null>(null);\n const roleRef = useRef<string | undefined>(undefined);\n const clientIdRef = useRef<string | undefined>(undefined);\n const autoConnectRef = useRef(true);\n const onMessageRef = useRef<(message: Message) => void | undefined>(undefined);\n const onTypingRef = useRef<((channelId: string, user: TypingUser) => void) | undefined>(undefined);\n const onConnectionChangeRef = useRef<((connected: boolean) => void) | undefined>(undefined);\n\n useEffect(() => {\n activeChannelIdRef.current = activeChannelId;\n }, [activeChannelId]);\n\n useEffect(() => {\n activeChannelIdRef.current = activeChannelId;\n }, [activeChannelId]);\n\n const getActiveChannelId = useCallback((): string | null => {\n if (typeof window === \"undefined\") return null;\n return sessionStorage.getItem(SESSION_STORAGE_KEY);\n }, []);\n\n const setActiveChannelId = useCallback((id: string | null) => {\n setActiveChannelIdState(id);\n if (typeof window !== \"undefined\") {\n if (id) {\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n } else {\n sessionStorage.removeItem(SESSION_STORAGE_KEY);\n }\n }\n }, []);\n\n const fetchFromComms = useCallback(\n async <T>(path: string, fetchOptions: RequestInit = {}): Promise<T> => {\n const currentSession = sessionRef.current;\n if (!currentSession) {\n throw new Error(\"Chat session not initialized\");\n }\n\n const response = await fetch(`${currentSession.api_url}${path}`, {\n ...fetchOptions,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${currentSession.access_token}`,\n ...fetchOptions.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n const data = await response.json();\n return data.data || data;\n },\n [],\n );\n\n const clearTimers = useCallback(() => {\n if (reconnectTimeout.current) {\n clearTimeout(reconnectTimeout.current);\n reconnectTimeout.current = null;\n }\n if (pingInterval.current) {\n clearInterval(pingInterval.current);\n pingInterval.current = null;\n }\n }, []);\n\n const handleWebSocketMessage = useCallback(\n (data: { type: string; payload: unknown }) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n console.log(\"[AegisChat] WebSocket message received:\", data.type, data);\n\n switch (data.type) {\n case \"message.new\": {\n const newMessage = data.payload as Message;\n if (newMessage.channel_id === currentActiveChannelId) {\n setMessages((prev) => {\n const existingIndex = prev.findIndex(\n (m) =>\n m.tempId &&\n m.content === newMessage.content &&\n m.status === \"sending\",\n );\n if (existingIndex !== -1) {\n const updated = [...prev];\n updated[existingIndex] = { ...newMessage, status: \"sent\" };\n return updated;\n }\n if (prev.some((m) => m.id === newMessage.id)) return prev;\n return [...prev, { ...newMessage, status: \"delivered\" }];\n });\n onMessageRef.current?.(newMessage);\n }\n setChannels((prev) => {\n const updated = prev.map((ch) =>\n ch.id === newMessage.channel_id\n ? {\n ...ch,\n last_message: {\n id: newMessage.id,\n content: newMessage.content,\n created_at: newMessage.created_at,\n sender: {\n id: newMessage.sender_id,\n display_name: \"Unknown\",\n status: \"online\" as const,\n },\n } as MessageSummary,\n unread_count:\n ch.id === currentActiveChannelId\n ? 0\n : ch.unread_count + 1,\n }\n : ch,\n );\n return updated.sort((a, b) => {\n const timeA = a.last_message?.created_at || \"\";\n const timeB = b.last_message?.created_at || \"\";\n return timeB.localeCompare(timeA);\n });\n });\n break;\n }\n case \"message.updated\": {\n const updatedMessage = data.payload as Message;\n setMessages((prev) =>\n prev.map((m) => (m.id === updatedMessage.id ? updatedMessage : m)),\n );\n break;\n }\n case \"message.deleted\": {\n const { message_id } = data.payload as { message_id: string };\n setMessages((prev) =>\n prev.map((m) =>\n m.id === message_id ? { ...m, deleted: true } : m,\n ),\n );\n break;\n }\n case \"message.delivered\":\n case \"message.read\": {\n const { message_id, channel_id, status } = data.payload as {\n message_id: string;\n channel_id: string;\n status: string;\n };\n if (channel_id === currentActiveChannelId) {\n setMessages((prev) =>\n prev.map((m) =>\n m.id === message_id\n ? {\n ...m,\n status: (status as Message[\"status\"]) || \"delivered\",\n }\n : m,\n ),\n );\n }\n break;\n }\n case \"message.delivered.batch\":\n case \"message.read.batch\": {\n const { channel_id } = data.payload as { channel_id: string };\n if (channel_id === currentActiveChannelId) {\n setMessages((prev) =>\n prev.map((m) =>\n m.status === \"sent\" || m.status === \"delivered\"\n ? {\n ...m,\n status:\n data.type === \"message.delivered.batch\"\n ? \"delivered\"\n : \"read\",\n }\n : m,\n ),\n );\n }\n break;\n }\n case \"typing.start\": {\n const { channel_id, user } = data.payload as {\n channel_id: string;\n user: UserSummary;\n };\n const typingUser: TypingUser = {\n id: user.id,\n displayName: user.display_name,\n avatarUrl: user.avatar_url,\n startedAt: Date.now(),\n };\n setTypingUsers((prev) => ({\n ...prev,\n [channel_id]: [\n ...(prev[channel_id] || []).filter((u) => u.id !== user.id),\n typingUser,\n ],\n }));\n onTypingRef.current?.(channel_id, typingUser);\n break;\n }\n case \"typing.stop\": {\n const { channel_id, user_id } = data.payload as {\n channel_id: string;\n user_id: string;\n };\n setTypingUsers((prev) => ({\n ...prev,\n [channel_id]: (prev[channel_id] || []).filter(\n (u) => u.id !== user_id,\n ),\n }));\n break;\n }\n case \"pong\":\n break;\n default:\n console.log(\"[AegisChat] Unhandled message type:\", data.type);\n }\n },\n [],\n );\n\n const connectWebSocket = useCallback(() => {\n const currentSession = sessionRef.current;\n if (!currentSession?.websocket_url || !currentSession?.access_token) {\n console.warn(\n \"[AegisChat] Cannot connect WebSocket - missing session or token\",\n );\n return;\n }\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n console.log(\"[AegisChat] WebSocket already open, skipping connection\");\n return;\n }\n\n setIsConnecting(true);\n isManualDisconnect.current = false;\n\n const wsUrl = `${currentSession.websocket_url}?token=${currentSession.access_token}`;\n console.log(\"[AegisChat] Creating WebSocket connection to:\", wsUrl);\n const ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n console.log(\"[AegisChat] WebSocket connected\");\n setIsConnected(true);\n setIsConnecting(false);\n reconnectAttempts.current = 0;\n onConnectionChangeRef.current?.(true);\n\n pingInterval.current = setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: \"ping\" }));\n }\n }, PING_INTERVAL);\n\n if (activeChannelIdRef.current) {\n ws.send(\n JSON.stringify({\n type: \"channel.join\",\n payload: { channel_id: activeChannelIdRef.current },\n }),\n );\n }\n };\n\n ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n handleWebSocketMessage(data);\n } catch (error) {\n console.error(\"[AegisChat] Failed to parse WebSocket message:\", error);\n }\n };\n\n ws.onclose = () => {\n console.log(\"[AegisChat] WebSocket disconnected\");\n setIsConnected(false);\n setIsConnecting(false);\n clearTimers();\n onConnectionChangeRef.current?.(false);\n\n if (\n !isManualDisconnect.current &&\n reconnectAttempts.current < MAX_RECONNECT_ATTEMPTS\n ) {\n const delay = Math.min(\n RECONNECT_INTERVAL * Math.pow(2, reconnectAttempts.current),\n MAX_RECONNECT_DELAY,\n );\n console.log(`[AegisChat] Reconnecting in ${delay}ms...`);\n reconnectTimeout.current = setTimeout(() => {\n reconnectAttempts.current++;\n connectWebSocket();\n }, delay);\n }\n };\n\n ws.onerror = (error) => {\n console.error(\"[AegisChat] WebSocket error:\", error);\n };\n\n wsRef.current = ws;\n }, [clearTimers, handleWebSocketMessage]);\n\n const connect = useCallback(async () => {\n console.log(\"[AegisChat] connect() called\");\n const targetSession = sessionRef.current;\n if (!targetSession) {\n console.log(\"[AegisChat] No session available, skipping connect\");\n return;\n }\n if (!autoConnectRef.current) {\n console.log(\"[AegisChat] autoConnect is false, skipping connect\");\n return;\n }\n connectWebSocket();\n }, [connectWebSocket]);\n\n const disconnect = useCallback(() => {\n isManualDisconnect.current = true;\n clearTimers();\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n setIsConnected(false);\n setSession(null);\n setChannels([]);\n setMessages([]);\n }, [clearTimers]);\n\n const refreshChannels = useCallback(async () => {\n const currentSession = sessionRef.current;\n if (!currentSession) return;\n\n setIsLoadingChannels(true);\n try {\n const response = await channelsApi.list({});\n setChannels(response.data.channels || []);\n } catch (error) {\n console.error(\"[AegisChat] Failed to fetch channels:\", error);\n } finally {\n setIsLoadingChannels(false);\n }\n }, []);\n\n const selectChannel = useCallback(\n async (channelId: string) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n setActiveChannelId(channelId);\n setMessages([]);\n setHasMoreMessages(true);\n oldestMessageId.current = null;\n\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n if (currentActiveChannelId) {\n wsRef.current.send(\n JSON.stringify({\n type: \"channel.leave\",\n payload: { channel_id: currentActiveChannelId },\n }),\n );\n }\n wsRef.current.send(\n JSON.stringify({\n type: \"channel.join\",\n payload: { channel_id: channelId },\n }),\n );\n }\n\n setIsLoadingMessages(true);\n try {\n const response = await fetchFromComms<MessagesResponse>(\n `/channels/${channelId}/messages?limit=50`,\n );\n setMessages(response.messages || []);\n setHasMoreMessages(response.has_more);\n if (response.oldest_id) {\n oldestMessageId.current = response.oldest_id;\n }\n\n await markAsRead(channelId);\n\n setChannels((prev) =>\n prev.map((ch) =>\n ch.id === channelId ? { ...ch, unread_count: 0 } : ch,\n ),\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to load messages:\", error);\n setMessages([]);\n } finally {\n setIsLoadingMessages(false);\n }\n },\n [setActiveChannelId, fetchFromComms],\n );\n\n const markAsRead = useCallback(\n async (channelId: string) => {\n try {\n await fetchFromComms(`/channels/${channelId}/read`, { method: \"POST\" });\n } catch (error) {\n console.error(\"[AegisChat] Failed to mark as read:\", error);\n }\n },\n [fetchFromComms],\n );\n\n const loadMoreMessages = useCallback(async () => {\n if (!activeChannelId || !hasMoreMessages || isLoadingMessages) return;\n\n setIsLoadingMessages(true);\n try {\n const params = oldestMessageId.current\n ? `?before=${oldestMessageId.current}&limit=50`\n : \"?limit=50\";\n const response = await fetchFromComms<MessagesResponse>(\n `/channels/${activeChannelId}/messages${params}`,\n );\n setMessages((prev) => [...(response.messages || []), ...prev]);\n setHasMoreMessages(response.has_more);\n if (response.oldest_id) {\n oldestMessageId.current = response.oldest_id;\n }\n } catch (error) {\n console.error(\"[AegisChat] Failed to load more messages:\", error);\n } finally {\n setIsLoadingMessages(false);\n }\n }, [activeChannelId, hasMoreMessages, isLoadingMessages, fetchFromComms]);\n\n const sendMessage = useCallback(\n async (\n content: string,\n msgOptions: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n } = {},\n ) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n const currentSession = sessionRef.current;\n if (!currentActiveChannelId || !content.trim() || !currentSession) return;\n\n const tempId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const trimmedContent = content.trim();\n\n const optimisticMessage: Message = {\n id: tempId,\n tempId,\n channel_id: currentActiveChannelId,\n sender_id: currentSession.comms_user_id,\n content: trimmedContent,\n type: (msgOptions.type as Message[\"type\"]) || \"text\",\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n status: \"sending\",\n metadata: msgOptions.metadata || {},\n };\n\n setMessages((prev) => [...prev, optimisticMessage]);\n\n const now = new Date().toISOString();\n setChannels((prev) => {\n const updated = prev.map((ch) =>\n ch.id === currentActiveChannelId\n ? {\n ...ch,\n last_message: {\n id: tempId,\n content: trimmedContent,\n created_at: now,\n sender: {\n id: currentSession.comms_user_id,\n display_name: \"You\",\n status: \"online\" as const,\n },\n },\n }\n : ch,\n );\n return updated.sort((a, b) => {\n const timeA = a.last_message?.created_at || \"\";\n const timeB = b.last_message?.created_at || \"\";\n return timeB.localeCompare(timeA);\n });\n });\n\n try {\n await fetchFromComms<Message>(\n `/channels/${currentActiveChannelId}/messages`,\n {\n method: \"POST\",\n body: JSON.stringify({\n content: trimmedContent,\n type: msgOptions.type || \"text\",\n parent_id: msgOptions.parent_id,\n metadata: msgOptions.metadata,\n }),\n },\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to send message:\", error);\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? {\n ...m,\n status: \"failed\",\n errorMessage:\n error instanceof Error ? error.message : \"Failed to send\",\n }\n : m,\n ),\n );\n throw error;\n }\n },\n [fetchFromComms],\n );\n\n const uploadFile = useCallback(\n async (file: File): Promise<FileAttachment | null> => {\n const currentSession = sessionRef.current;\n if (!currentSession) return null;\n\n const fileId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n setUploadProgress((prev) => [\n ...prev,\n { fileId, fileName: file.name, progress: 0, status: \"pending\" },\n ]);\n\n try {\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === fileId\n ? { ...p, status: \"uploading\", progress: 10 }\n : p,\n ),\n );\n\n const uploadUrlResponse = await fetchFromComms<{\n upload_url: string;\n file_id: string;\n expires_at: string;\n }>(\"/files/upload-url\", {\n method: \"POST\",\n body: JSON.stringify({\n file_name: file.name,\n file_type: file.type || \"application/octet-stream\",\n file_size: file.size,\n }),\n });\n\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === fileId\n ? { ...p, fileId: uploadUrlResponse.file_id, progress: 30 }\n : p,\n ),\n );\n\n const uploadResponse = await fetch(uploadUrlResponse.upload_url, {\n method: \"PUT\",\n body: file,\n headers: { \"Content-Type\": file.type || \"application/octet-stream\" },\n });\n\n if (!uploadResponse.ok)\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === uploadUrlResponse.file_id\n ? { ...p, status: \"confirming\", progress: 70 }\n : p,\n ),\n );\n\n const confirmResponse = await fetchFromComms<{ file: FileAttachment }>(\n \"/files\",\n {\n method: \"POST\",\n body: JSON.stringify({ file_id: uploadUrlResponse.file_id }),\n },\n );\n\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === uploadUrlResponse.file_id\n ? { ...p, status: \"complete\", progress: 100 }\n : p,\n ),\n );\n setTimeout(\n () =>\n setUploadProgress((prev) =>\n prev.filter((p) => p.fileId !== uploadUrlResponse.file_id),\n ),\n 2000,\n );\n\n return confirmResponse.file;\n } catch (error) {\n console.error(\"[AegisChat] Failed to upload file:\", error);\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === fileId\n ? {\n ...p,\n status: \"error\",\n error:\n error instanceof Error ? error.message : \"Upload failed\",\n }\n : p,\n ),\n );\n setTimeout(\n () =>\n setUploadProgress((prev) =>\n prev.filter((p) => p.fileId !== fileId),\n ),\n 5000,\n );\n return null;\n }\n },\n [fetchFromComms],\n );\n\n const sendMessageWithFiles = useCallback(\n async (\n content: string,\n files: File[],\n msgOptions: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n } = {},\n ) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n const currentSession = sessionRef.current;\n if (\n !currentActiveChannelId ||\n (!content.trim() && files.length === 0) ||\n !currentSession\n )\n return;\n\n const tempId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const trimmedContent = content.trim();\n\n const optimisticMessage: Message = {\n id: tempId,\n tempId,\n channel_id: currentActiveChannelId,\n sender_id: currentSession.comms_user_id,\n content: trimmedContent || `Uploading ${files.length} file(s)...`,\n type: \"file\",\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n status: \"sending\",\n metadata: {\n ...msgOptions.metadata,\n files: files.map((f) => ({\n id: `temp-${f.name}`,\n filename: f.name,\n mime_type: f.type,\n size: f.size,\n url: \"\",\n })),\n },\n };\n\n setMessages((prev) => [...prev, optimisticMessage]);\n\n try {\n const uploadedFiles: FileAttachment[] = [];\n for (const file of files) {\n const attachment = await uploadFile(file);\n if (attachment) uploadedFiles.push(attachment);\n }\n\n const messageType =\n uploadedFiles.length > 0 && !trimmedContent ? \"file\" : \"text\";\n\n await fetchFromComms<Message>(\n `/channels/${currentActiveChannelId}/messages`,\n {\n method: \"POST\",\n body: JSON.stringify({\n content:\n trimmedContent ||\n (uploadedFiles.length > 0\n ? `Shared ${uploadedFiles.length} file(s)`\n : \"\"),\n type: msgOptions.type || messageType,\n parent_id: msgOptions.parent_id,\n metadata: { ...msgOptions.metadata, files: uploadedFiles },\n file_ids: uploadedFiles.map((f) => f.id),\n }),\n },\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to send message with files:\", error);\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? {\n ...m,\n status: \"failed\",\n errorMessage:\n error instanceof Error ? error.message : \"Failed to send\",\n }\n : m,\n ),\n );\n throw error;\n }\n },\n [fetchFromComms, uploadFile],\n );\n\n const stopTyping = useCallback(() => {\n const currentActiveChannelId = activeChannelIdRef.current;\n if (!currentActiveChannelId || !wsRef.current) return;\n wsRef.current.send(\n JSON.stringify({\n type: \"typing.stop\",\n payload: { channel_id: currentActiveChannelId },\n }),\n );\n if (typingTimeout.current) {\n clearTimeout(typingTimeout.current);\n typingTimeout.current = null;\n }\n }, []);\n\n const startTyping = useCallback(() => {\n const currentActiveChannelId = activeChannelIdRef.current;\n if (!currentActiveChannelId || !wsRef.current) return;\n wsRef.current.send(\n JSON.stringify({\n type: \"typing.start\",\n payload: { channel_id: currentActiveChannelId },\n }),\n );\n if (typingTimeout.current) clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(stopTyping, TYPING_TIMEOUT);\n }, [stopTyping]);\n\n const createDMWithUser = useCallback(\n async (userId: string): Promise<string | null> => {\n try {\n const channel = await fetchFromComms<{ id: string }>(\"/channels/dm\", {\n method: \"POST\",\n body: JSON.stringify({ user_id: userId }),\n });\n await refreshChannels();\n return channel.id;\n } catch (error) {\n console.error(\"[AegisChat] Failed to create DM:\", error);\n return null;\n }\n },\n [fetchFromComms, refreshChannels],\n );\n\n const retryMessage = useCallback(\n async (tempId: string) => {\n const failedMessage = messages.find(\n (m) => m.tempId === tempId && m.status === \"failed\",\n );\n const currentActiveChannelId = activeChannelIdRef.current;\n if (!failedMessage || !currentActiveChannelId) return;\n\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? { ...m, status: \"sending\", errorMessage: undefined }\n : m,\n ),\n );\n\n try {\n await fetchFromComms<Message>(\n `/channels/${currentActiveChannelId}/messages`,\n {\n method: \"POST\",\n body: JSON.stringify({\n content: failedMessage.content,\n type: failedMessage.type,\n metadata: failedMessage.metadata,\n }),\n },\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to retry message:\", error);\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? {\n ...m,\n status: \"failed\",\n errorMessage:\n error instanceof Error ? error.message : \"Failed to send\",\n }\n : m,\n ),\n );\n }\n },\n [messages, fetchFromComms],\n );\n\n const deleteFailedMessage = useCallback((tempId: string) => {\n setMessages((prev) => prev.filter((m) => m.tempId !== tempId));\n }, []);\n\n const setup = useCallback((options: UseChatOptions) => {\n const {\n config,\n role,\n clientId,\n initialSession,\n autoConnect = true,\n onMessage,\n onTyping,\n onConnectionChange,\n } = options;\n\n roleRef.current = role;\n clientIdRef.current = clientId;\n autoConnectRef.current = autoConnect;\n onMessageRef.current = onMessage;\n onTypingRef.current = onTyping;\n onConnectionChangeRef.current = onConnectionChange;\n\n if (initialSession) {\n sessionRef.current = initialSession;\n\n if (!config) {\n const url = initialSession.api_url;\n const normalizedUrl = url.includes('/api/v1') || url.includes('/v')\n ? url\n : `${url}/api/v1`;\n configureApiClient({\n baseUrl: normalizedUrl,\n getAccessToken: async () => sessionRef.current?.access_token || \"\",\n });\n }\n\n setSession(initialSession);\n }\n }, []);\n\n useEffect(() => {\n if (session && !isConnected && !isConnecting && autoConnectRef.current) {\n connectWebSocket();\n }\n }, [session, isConnected, isConnecting, connectWebSocket]);\n\n useEffect(() => {\n if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {\n wsRef.current.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n handleWebSocketMessage(data);\n } catch (error) {\n console.error(\n \"[AegisChat] Failed to parse WebSocket message:\",\n error,\n );\n }\n };\n }\n }, [handleWebSocketMessage]);\n\n useEffect(() => {\n if (isConnected && channels.length === 0) {\n refreshChannels();\n }\n }, [isConnected, channels.length, refreshChannels]);\n\n useEffect(() => {\n const storedActiveChannel = getActiveChannelId();\n if (storedActiveChannel && !activeChannelId) {\n selectChannel(storedActiveChannel);\n }\n }, [getActiveChannelId, activeChannelId, selectChannel]);\n\n useEffect(() => {\n return () => {\n clearTimers();\n if (typingTimeout.current) clearTimeout(typingTimeout.current);\n if (wsRef.current) {\n isManualDisconnect.current = true;\n wsRef.current.close();\n wsRef.current = null;\n }\n };\n }, [clearTimers]);\n\n return {\n session,\n isConnected,\n isConnecting,\n channels,\n messages,\n activeChannelId,\n typingUsers: activeChannelId ? typingUsers[activeChannelId] || [] : [],\n isLoadingChannels,\n isLoadingMessages,\n hasMoreMessages,\n uploadProgress,\n connect,\n disconnect,\n selectChannel,\n sendMessage,\n sendMessageWithFiles,\n uploadFile,\n loadMoreMessages,\n startTyping,\n stopTyping,\n refreshChannels,\n createDMWithUser,\n retryMessage,\n deleteFailedMessage,\n markAsRead,\n setup,\n };\n}\n\nexport default useChat;\n","// ============================================================================\n// AegisChat React SDK - API Service\n// ============================================================================\n\nimport type {\n ApiResponse,\n ChatSession,\n ChatConnectParams,\n Channel,\n ChannelListItem,\n Message,\n MessagesResponse,\n UserSummary,\n ReactionSummary,\n FileAttachment,\n UploadUrlResponse,\n} from '../types';\n\nlet baseUrl = '';\nlet getAccessToken: () => Promise<string> | string = () => '';\nlet onUnauthorized: (() => void) | undefined;\n\nexport function configureApiClient(config: {\n baseUrl: string;\n getAccessToken: () => Promise<string> | string;\n onUnauthorized?: () => void;\n}): void {\n baseUrl = config.baseUrl;\n getAccessToken = config.getAccessToken;\n onUnauthorized = config.onUnauthorized;\n}\n\nasync function fetchWithAuth<T>(\n path: string,\n options: RequestInit = {}\n): Promise<T> {\n const token = await (typeof getAccessToken === 'function' \n ? getAccessToken() \n : getAccessToken);\n\n const response = await fetch(`${baseUrl}${path}`, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n ...options.headers,\n },\n });\n\n if (response.status === 401) {\n onUnauthorized?.();\n throw new Error('Unauthorized');\n }\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n return response.json();\n}\n\nexport const chatApi = {\n /**\n * Connect to chat session\n */\n async connect(\n params: ChatConnectParams,\n signal?: AbortSignal\n ): Promise<ApiResponse<ChatSession>> {\n return fetchWithAuth('/api/v1/chat/connect', {\n method: 'POST',\n body: JSON.stringify(params),\n signal,\n });\n },\n\n /**\n * Refresh access token\n */\n async refreshToken(\n refreshToken: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ access_token: string; expires_in: number }>> {\n return fetchWithAuth('/api/v1/chat/refresh', {\n method: 'POST',\n body: JSON.stringify({ refresh_token: refreshToken }),\n signal,\n });\n },\n};\n\nexport const channelsApi = {\n /**\n * List channels\n */\n async list(\n options: { type?: string; limit?: number } = {},\n signal?: AbortSignal\n ): Promise<ApiResponse<{ channels: ChannelListItem[] }>> {\n const params = new URLSearchParams();\n if (options.type) params.append('type', options.type);\n if (options.limit) params.append('limit', String(options.limit));\n const query = params.toString() ? `?${params.toString()}` : '';\n return fetchWithAuth(`/api/v1/channels${query}`, { signal });\n },\n\n /**\n * Get channel by ID\n */\n async get(channelId: string, signal?: AbortSignal): Promise<ApiResponse<Channel>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}`, { signal });\n },\n\n /**\n * Get or create DM channel\n */\n async getOrCreateDM(\n userId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<Channel>> {\n return fetchWithAuth('/api/v1/channels/dm', {\n method: 'POST',\n body: JSON.stringify({ user_id: userId }),\n signal,\n });\n },\n\n /**\n * Create channel\n */\n async create(\n data: { name: string; type?: string; description?: string; metadata?: Record<string, unknown> },\n signal?: AbortSignal\n ): Promise<ApiResponse<Channel>> {\n return fetchWithAuth('/api/v1/channels', {\n method: 'POST',\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Mark channel as read\n */\n async markAsRead(\n channelId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ unread_count: number }>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/read`, {\n method: 'POST',\n signal,\n });\n },\n\n /**\n * Get channel members\n */\n async getMembers(\n channelId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ members: UserSummary[] }>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/members`, { signal });\n },\n\n /**\n * Update channel\n */\n async update(\n channelId: string,\n data: { name?: string; description?: string; metadata?: Record<string, unknown> },\n signal?: AbortSignal\n ): Promise<ApiResponse<Channel>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}`, {\n method: 'PATCH',\n body: JSON.stringify(data),\n signal,\n });\n },\n};\n\nexport const messagesApi = {\n /**\n * List messages in a channel\n */\n async list(\n channelId: string,\n options: { limit?: number; before?: string } = {},\n signal?: AbortSignal\n ): Promise<ApiResponse<MessagesResponse>> {\n const params = new URLSearchParams();\n if (options.limit) params.append('limit', String(options.limit));\n if (options.before) params.append('before', options.before);\n const query = params.toString() ? `?${params.toString()}` : '';\n return fetchWithAuth(`/api/v1/channels/${channelId}/messages${query}`, { signal });\n },\n\n /**\n * Send a message\n */\n async send(\n channelId: string,\n data: { content: string; type?: string; parent_id?: string; metadata?: Record<string, unknown>; file_ids?: string[] },\n signal?: AbortSignal\n ): Promise<ApiResponse<Message>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/messages`, {\n method: 'POST',\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Update a message\n */\n async update(\n channelId: string,\n messageId: string,\n data: { content?: string; metadata?: Record<string, unknown> },\n signal?: AbortSignal\n ): Promise<ApiResponse<Message>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/messages/${messageId}`, {\n method: 'PATCH',\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Delete a message\n */\n async delete(\n channelId: string,\n messageId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ success: boolean }>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/messages/${messageId}`, {\n method: 'DELETE',\n signal,\n });\n },\n\n /**\n * Mark messages as delivered\n */\n async markDelivered(\n channelId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ success: boolean }>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/messages/delivered`, {\n method: 'POST',\n signal,\n });\n },\n\n /**\n * Mark messages as read\n */\n async markRead(\n channelId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ success: boolean }>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/messages/read`, {\n method: 'POST',\n signal,\n });\n },\n};\n\nexport const reactionsApi = {\n /**\n * Add reaction to a message\n */\n async add(\n channelId: string,\n messageId: string,\n emoji: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ reactions: ReactionSummary[] }>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/messages/${messageId}/reactions`, {\n method: 'POST',\n body: JSON.stringify({ emoji }),\n signal,\n });\n },\n\n /**\n * Remove reaction from a message\n */\n async remove(\n channelId: string,\n messageId: string,\n emoji: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ reactions: ReactionSummary[] }>> {\n return fetchWithAuth(\n `/api/v1/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`,\n { method: 'DELETE', signal }\n );\n },\n};\n\nexport const filesApi = {\n /**\n * Get upload URL\n */\n async getUploadUrl(\n data: { file_name: string; file_type: string; file_size: number },\n signal?: AbortSignal\n ): Promise<ApiResponse<UploadUrlResponse>> {\n return fetchWithAuth('/api/v1/files/upload-url', {\n method: 'POST',\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Confirm file upload\n */\n async confirm(\n fileId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ file: FileAttachment }>> {\n return fetchWithAuth('/api/v1/files', {\n method: 'POST',\n body: JSON.stringify({ file_id: fileId }),\n signal,\n });\n },\n\n /**\n * Get download URL\n */\n async getDownloadUrl(\n fileId: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ url: string; expires_at: string }>> {\n return fetchWithAuth(`/api/v1/files/${fileId}/download`, { signal });\n },\n};\n\nexport const usersApi = {\n /**\n * Search users\n */\n async search(\n query: string,\n signal?: AbortSignal\n ): Promise<ApiResponse<{ users: UserSummary[] }>> {\n return fetchWithAuth(`/api/v1/users/search?q=${encodeURIComponent(query)}`, { signal });\n },\n\n /**\n * Get user by ID\n */\n async get(userId: string, signal?: AbortSignal): Promise<ApiResponse<UserSummary>> {\n return fetchWithAuth(`/api/v1/users/${userId}`, { signal });\n },\n};\n\nexport default {\n chatApi,\n channelsApi,\n messagesApi,\n reactionsApi,\n filesApi,\n usersApi,\n configureApiClient,\n};\n","// ============================================================================\n// AegisChat React SDK - useAutoRead Hook\n// ============================================================================\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { channelsApi } from '../services/api';\n\nconst SESSION_STORAGE_KEY = '@aegischat/activeChannel';\n\nexport interface UseAutoReadOptions {\n onMarkAsRead?: (channelId: string) => void;\n}\n\nexport interface UseAutoReadReturn {\n markAsRead: (channelId: string) => Promise<void>;\n markAllAsRead: () => Promise<void>;\n isFocused: boolean;\n}\n\nexport function useAutoRead(options: UseAutoReadOptions = {}): UseAutoReadReturn {\n const [isFocused, setIsFocused] = useState(false);\n\n useEffect(() => {\n setIsFocused(typeof document !== 'undefined' && document.hasFocus());\n\n const handleFocus = () => setIsFocused(true);\n const handleBlur = () => setIsFocused(false);\n\n window.addEventListener('focus', handleFocus);\n window.addEventListener('blur', handleBlur);\n\n return () => {\n window.removeEventListener('focus', handleFocus);\n window.removeEventListener('blur', handleBlur);\n };\n }, []);\n\n useEffect(() => {\n const handleVisibilityChange = () => {\n if (!document.hidden) {\n const activeChannelId = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (activeChannelId) {\n markAsRead(activeChannelId);\n }\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => document.removeEventListener('visibilitychange', handleVisibilityChange);\n }, []);\n\n const markAsRead = useCallback(async (channelId: string) => {\n if (!isFocused) return;\n try {\n await channelsApi.markAsRead(channelId);\n options.onMarkAsRead?.(channelId);\n } catch (error) {\n console.error('[AegisChat] useAutoRead: Failed to mark as read:', error);\n }\n }, [isFocused, options.onMarkAsRead]);\n\n const markAllAsRead = useCallback(async () => {\n if (!isFocused) return;\n try {\n const response = await channelsApi.list({});\n const channels = response.data.channels || [];\n await Promise.all(\n channels.filter((ch) => ch.unread_count > 0).map((ch) => channelsApi.markAsRead(ch.id))\n );\n } catch (error) {\n console.error('[AegisChat] useAutoRead: Failed to mark all as read:', error);\n }\n }, [isFocused]);\n\n return { markAsRead, markAllAsRead, isFocused };\n}\n\nexport default useAutoRead;\n","// ============================================================================\n// AegisChat React SDK - useChannels Hook\n// ============================================================================\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { channelsApi } from '../services/api';\nimport type { ChannelListItem, Channel } from '../types';\n\nexport interface UseChannelsOptions {\n type?: 'direct' | 'public' | 'private';\n limit?: number;\n autoFetch?: boolean;\n onChannelCreated?: (channel: Channel) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface UseChannelsReturn {\n channels: ChannelListItem[];\n isLoading: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n getOrCreateDM: (userId: string) => Promise<Channel>;\n markAsRead: (channelId: string) => Promise<void>;\n}\n\nexport function useChannels(options: UseChannelsOptions = {}): UseChannelsReturn {\n const { type, limit = 20, autoFetch = true, onChannelCreated, onError } = options;\n\n const [channels, setChannels] = useState<ChannelListItem[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const fetchChannels = useCallback(async (signal?: AbortSignal) => {\n setIsLoading(true);\n setError(null);\n\n try {\n const response = await channelsApi.list({ type, limit }, signal);\n if (signal?.aborted) return;\n setChannels(response.data.channels);\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') return;\n const error = err instanceof Error ? err : new Error('Failed to fetch channels');\n setError(error);\n onError?.(error);\n } finally {\n if (!signal?.aborted) setIsLoading(false);\n }\n }, [type, limit, onError]);\n\n const refetch = useCallback(async () => {\n if (abortControllerRef.current) abortControllerRef.current.abort();\n const controller = new AbortController();\n abortControllerRef.current = controller;\n await fetchChannels(controller.signal);\n }, [fetchChannels]);\n\n const getOrCreateDM = useCallback(async (userId: string): Promise<Channel> => {\n try {\n const response = await channelsApi.getOrCreateDM(userId);\n if (abortControllerRef.current) abortControllerRef.current.abort();\n const controller = new AbortController();\n abortControllerRef.current = controller;\n fetchChannels(controller.signal);\n onChannelCreated?.(response.data);\n return response.data;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to create DM');\n onError?.(error);\n throw error;\n }\n }, [fetchChannels, onChannelCreated, onError]);\n\n const markAsRead = useCallback(async (channelId: string): Promise<void> => {\n try {\n await channelsApi.markAsRead(channelId);\n setChannels((prev) => prev.map((ch) => ch.id === channelId ? { ...ch, unread_count: 0 } : ch));\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to mark as read');\n onError?.(error);\n throw error;\n }\n }, [onError]);\n\n useEffect(() => {\n if (autoFetch) {\n if (abortControllerRef.current) abortControllerRef.current.abort();\n const controller = new AbortController();\n abortControllerRef.current = controller;\n fetchChannels(controller.signal);\n return () => controller.abort();\n }\n }, [autoFetch, fetchChannels]);\n\n return { channels, isLoading, error, refetch, getOrCreateDM, markAsRead };\n}\n\nexport default useChannels;\n","// ============================================================================\n// AegisChat React SDK - useMessages Hook\n// ============================================================================\n\nimport { useCallback, useState } from 'react';\nimport { messagesApi } from '../services/api';\nimport type { Message, MessagesResponse } from '../types';\n\nexport interface UseMessagesOptions {\n channelId: string;\n}\n\nexport interface UseMessagesReturn {\n messages: Message[];\n isLoading: boolean;\n hasMore: boolean;\n sendMessage: (params: { content: string; type?: string; metadata?: Record<string, unknown> }) => Promise<void>;\n loadMore: () => Promise<void>;\n}\n\nexport function useMessages(_options: UseMessagesOptions): UseMessagesReturn {\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n\n const sendMessage = useCallback(async (params: { content: string; type?: string; metadata?: Record<string, unknown> }) => {\n // Implementation would go here\n }, []);\n\n const loadMore = useCallback(async () => {\n // Implementation would go here\n }, []);\n\n return { messages, isLoading, hasMore, sendMessage, loadMore };\n}\n\nexport default useMessages;\n","// ============================================================================\n// AegisChat React SDK - useTypingIndicator Hook\n// ============================================================================\n\nimport { useCallback, useState } from 'react';\nimport type { TypingUser } from '../types';\n\nexport interface UseTypingIndicatorOptions {\n channelId: string;\n ws?: WebSocket | null;\n}\n\nexport interface UseTypingIndicatorReturn {\n typingUsers: TypingUser[];\n startTyping: () => void;\n stopTyping: () => void;\n}\n\nexport function useTypingIndicator(_options: UseTypingIndicatorOptions): UseTypingIndicatorReturn {\n const [typingUsers, setTypingUsers] = useState<TypingUser[]>([]);\n\n const startTyping = useCallback(() => {}, []);\n const stopTyping = useCallback(() => {}, []);\n\n return { typingUsers, startTyping, stopTyping };\n}\n\nexport default useTypingIndicator;\n","// ============================================================================\n// AegisChat React SDK - useReactions Hook\n// ============================================================================\n\nimport { useState } from 'react';\nimport type { ReactionSummary } from '../types';\n\nexport interface UseReactionsOptions {\n channelId: string;\n messageId: string;\n}\n\nexport interface UseReactionsReturn {\n reactions: ReactionSummary[];\n addReaction: (emoji: string) => Promise<void>;\n removeReaction: (emoji: string) => Promise<void>;\n}\n\nexport function useReactions(_options: UseReactionsOptions): UseReactionsReturn {\n const [reactions, setReactions] = useState<ReactionSummary[]>([]);\n\n const addReaction = async (_emoji: string) => {};\n const removeReaction = async (_emoji: string) => {};\n\n return { reactions, addReaction, removeReaction };\n}\n\nexport default useReactions;\n","// ============================================================================\n// AegisChat React SDK - useFileUpload Hook\n// ============================================================================\n\nimport { useState } from 'react';\nimport type { FileAttachment, UploadProgress } from '../types';\n\nexport interface UseFileUploadOptions {\n channelId: string;\n}\n\nexport interface UseFileUploadReturn {\n uploadProgress: UploadProgress[];\n upload: (file: File) => Promise<FileAttachment | null>;\n}\n\nexport function useFileUpload(_options: UseFileUploadOptions): UseFileUploadReturn {\n const [uploadProgress, setUploadProgress] = useState<UploadProgress[]>([]);\n\n const upload = async (_file: File): Promise<FileAttachment | null> => null;\n\n return { uploadProgress, upload };\n}\n\nexport default useFileUpload;\n","// ============================================================================\n// AegisChat React SDK - useMentions Hook\n// ============================================================================\n\nexport interface UseMentionsOptions {}\n\nexport interface UseMentionsReturn {\n parseMentions: (content: string) => string[];\n highlightMentions: (content: string) => string;\n isUserMentioned: (content: string, userId: string) => boolean;\n}\n\nexport function useMentions(_options: UseMentionsOptions = {}): UseMentionsReturn {\n const parseMentions = (content: string): string[] => {\n const mentionRegex = /@\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n const mentions: string[] = [];\n let match;\n while ((match = mentionRegex.exec(content)) !== null) {\n mentions.push(match[2]);\n }\n return mentions;\n };\n\n const highlightMentions = (content: string): string => {\n return content.replace(/@\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<span class=\"mention\">@$1</span>');\n };\n\n const isUserMentioned = (content: string, userId: string): boolean => {\n const mentions = parseMentions(content);\n return mentions.includes(userId);\n };\n\n return { parseMentions, highlightMentions, isUserMentioned };\n}\n\nexport default useMentions;\n"],"mappings":"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","names":["options","config","role","clientId","initialSession","autoConnect","onMessage","onTyping","onConnectionChange","import_react","SESSION_STORAGE_KEY","import_react","error","import_react","import_react","import_react","import_react"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/useChat.ts","../src/services/api.ts","../src/hooks/useAutoRead.ts","../src/hooks/useChannels.ts","../src/hooks/useMessages.ts","../src/hooks/useTypingIndicator.ts","../src/hooks/useReactions.ts","../src/hooks/useFileUpload.ts","../src/hooks/useMentions.ts"],"sourcesContent":["// ============================================================================\n// AegisChat React SDK - Main Entry Point\n// ============================================================================\n\nexport { useChat } from './hooks/useChat';\nexport type { UseChatOptions, UseChatReturn } from './hooks/useChat';\n\nexport { useAutoRead } from './hooks/useAutoRead';\nexport type { UseAutoReadOptions, UseAutoReadReturn } from './hooks/useAutoRead';\n\nexport { useChannels } from './hooks/useChannels';\nexport type { UseChannelsOptions, UseChannelsReturn } from './hooks/useChannels';\n\nexport { useMessages } from './hooks/useMessages';\nexport type { UseMessagesOptions, UseMessagesReturn } from './hooks/useMessages';\n\nexport { useTypingIndicator } from './hooks/useTypingIndicator';\nexport type { UseTypingIndicatorOptions } from './hooks/useTypingIndicator';\n\nexport { useReactions } from './hooks/useReactions';\nexport type { UseReactionsOptions } from './hooks/useReactions';\n\nexport { useFileUpload } from './hooks/useFileUpload';\nexport type { UseFileUploadOptions } from './hooks/useFileUpload';\n\nexport { useMentions } from './hooks/useMentions';\nexport type { UseMentionsOptions } from './hooks/useMentions';\n\nexport {\n chatApi,\n channelsApi,\n messagesApi,\n reactionsApi,\n filesApi,\n usersApi,\n configureApiClient,\n} from './services/api';\n\nexport type {\n AegisConfig,\n ChatSession,\n ChatConnectParams,\n UserSummary,\n UserStatus,\n Channel,\n ChannelListItem,\n ChannelType,\n Message,\n MessageSummary,\n MessageType,\n MessageStatus,\n MessageMetadata,\n FileAttachment,\n TypingUser,\n TypingEvent,\n ReactionSummary,\n ReactionEvent,\n UploadProgress,\n WebSocketMessage,\n WebSocketStatus,\n ApiResponse,\n ApiError,\n PaginationParams,\n PaginationMeta,\n PaginatedResponse,\n MessagesResponse,\n ChannelsResponse,\n} from './types';\n","// ============================================================================\n// AegisChat React SDK - useChat Hook\n// ============================================================================\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n chatApi,\n channelsApi,\n messagesApi,\n filesApi,\n configureApiClient,\n} from \"../services/api\";\nimport type {\n AegisConfig,\n ChatSession,\n ChannelListItem,\n Message,\n MessagesResponse,\n TypingUser,\n UserSummary,\n FileAttachment,\n UploadProgress,\n MessageSummary,\n} from \"../types\";\n\nconst TYPING_TIMEOUT = 3000;\nconst RECONNECT_INTERVAL = 3000;\nconst MAX_RECONNECT_ATTEMPTS = 5;\nconst MAX_RECONNECT_DELAY = 30000;\nconst PING_INTERVAL = 30000;\nconst SESSION_STORAGE_KEY = \"@aegischat/activeChannel\";\n\nexport interface UseChatOptions {\n config?: AegisConfig;\n role?: \"lawyer\" | \"client\";\n clientId?: string;\n\n initialSession?: ChatSession | null;\n autoConnect?: boolean;\n onMessage?: (message: Message) => void;\n onTyping?: (channelId: string, user: TypingUser) => void;\n onConnectionChange?: (connected: boolean) => void;\n}\n\nexport interface UseChatReturn {\n session: ChatSession | null;\n isConnected: boolean;\n isConnecting: boolean;\n channels: ChannelListItem[];\n messages: Message[];\n activeChannelId: string | null;\n typingUsers: TypingUser[];\n isLoadingChannels: boolean;\n isLoadingMessages: boolean;\n hasMoreMessages: boolean;\n uploadProgress: UploadProgress[];\n connect: () => Promise<void>;\n disconnect: () => void;\n selectChannel: (channelId: string) => void;\n sendMessage: (\n content: string,\n options?: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n },\n ) => Promise<void>;\n sendMessageWithFiles: (\n content: string,\n files: File[],\n options?: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n },\n ) => Promise<void>;\n uploadFile: (file: File) => Promise<FileAttachment | null>;\n loadMoreMessages: () => Promise<void>;\n startTyping: () => void;\n stopTyping: () => void;\n refreshChannels: () => Promise<void>;\n createDMWithUser: (userId: string) => Promise<string | null>;\n retryMessage: (tempId: string) => Promise<void>;\n deleteFailedMessage: (tempId: string) => void;\n markAsRead: (channelId: string) => Promise<void>;\n setup: (options: UseChatOptions) => void;\n}\n\nexport function useChat(options: Partial<UseChatOptions> = {}): UseChatReturn {\n const {\n config,\n role,\n clientId,\n initialSession,\n autoConnect = true,\n onMessage,\n onTyping,\n onConnectionChange,\n } = options;\n\n const [session, setSession] = useState<ChatSession | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [isConnecting, setIsConnecting] = useState(false);\n const [activeChannelId, setActiveChannelIdState] = useState<string | null>(\n null,\n );\n const [channels, setChannels] = useState<ChannelListItem[]>([]);\n const [messages, setMessages] = useState<Message[]>([]);\n const [typingUsers, setTypingUsers] = useState<Record<string, TypingUser[]>>(\n {},\n );\n const [isLoadingChannels, setIsLoadingChannels] = useState(false);\n const [isLoadingMessages, setIsLoadingMessages] = useState(false);\n const [hasMoreMessages, setHasMoreMessages] = useState(true);\n const [uploadProgress, setUploadProgress] = useState<UploadProgress[]>([]);\n\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectAttempts = useRef(0);\n const reconnectTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pingInterval = useRef<ReturnType<typeof setInterval> | null>(null);\n const typingTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isManualDisconnect = useRef(false);\n const oldestMessageId = useRef<string | null>(null);\n const activeChannelIdRef = useRef<string | null>(null);\n const sessionRef = useRef<ChatSession | null>(null);\n const roleRef = useRef<string | undefined>(undefined);\n const clientIdRef = useRef<string | undefined>(undefined);\n const autoConnectRef = useRef(true);\n const onMessageRef = useRef<(message: Message) => void | undefined>(undefined);\n const onTypingRef = useRef<((channelId: string, user: TypingUser) => void) | undefined>(undefined);\n const onConnectionChangeRef = useRef<((connected: boolean) => void) | undefined>(undefined);\n\n useEffect(() => {\n activeChannelIdRef.current = activeChannelId;\n }, [activeChannelId]);\n\n useEffect(() => {\n activeChannelIdRef.current = activeChannelId;\n }, [activeChannelId]);\n\n const getActiveChannelId = useCallback((): string | null => {\n if (typeof window === \"undefined\") return null;\n return sessionStorage.getItem(SESSION_STORAGE_KEY);\n }, []);\n\n const setActiveChannelId = useCallback((id: string | null) => {\n setActiveChannelIdState(id);\n if (typeof window !== \"undefined\") {\n if (id) {\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n } else {\n sessionStorage.removeItem(SESSION_STORAGE_KEY);\n }\n }\n }, []);\n\n const fetchFromComms = useCallback(\n async <T>(path: string, fetchOptions: RequestInit = {}): Promise<T> => {\n const currentSession = sessionRef.current;\n if (!currentSession) {\n throw new Error(\"Chat session not initialized\");\n }\n\n const response = await fetch(`${currentSession.api_url}${path}`, {\n ...fetchOptions,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${currentSession.access_token}`,\n ...fetchOptions.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n const data = await response.json();\n return data.data || data;\n },\n [],\n );\n\n const clearTimers = useCallback(() => {\n if (reconnectTimeout.current) {\n clearTimeout(reconnectTimeout.current);\n reconnectTimeout.current = null;\n }\n if (pingInterval.current) {\n clearInterval(pingInterval.current);\n pingInterval.current = null;\n }\n }, []);\n\n const handleWebSocketMessage = useCallback(\n (data: { type: string; payload: unknown }) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n console.log(\"[AegisChat] WebSocket message received:\", data.type, data);\n\n switch (data.type) {\n case \"message.new\": {\n const newMessage = data.payload as Message;\n if (newMessage.channel_id === currentActiveChannelId) {\n setMessages((prev) => {\n const existingIndex = prev.findIndex(\n (m) =>\n m.tempId &&\n m.content === newMessage.content &&\n m.status === \"sending\",\n );\n if (existingIndex !== -1) {\n const updated = [...prev];\n updated[existingIndex] = { ...newMessage, status: \"sent\" };\n return updated;\n }\n if (prev.some((m) => m.id === newMessage.id)) return prev;\n return [...prev, { ...newMessage, status: \"delivered\" }];\n });\n onMessageRef.current?.(newMessage);\n }\n setChannels((prev) => {\n const updated = prev.map((ch) =>\n ch.id === newMessage.channel_id\n ? {\n ...ch,\n last_message: {\n id: newMessage.id,\n content: newMessage.content,\n created_at: newMessage.created_at,\n sender: {\n id: newMessage.sender_id,\n display_name: \"Unknown\",\n status: \"online\" as const,\n },\n } as MessageSummary,\n unread_count:\n ch.id === currentActiveChannelId\n ? 0\n : ch.unread_count + 1,\n }\n : ch,\n );\n return updated.sort((a, b) => {\n const timeA = a.last_message?.created_at || \"\";\n const timeB = b.last_message?.created_at || \"\";\n return timeB.localeCompare(timeA);\n });\n });\n break;\n }\n case \"message.updated\": {\n const updatedMessage = data.payload as Message;\n setMessages((prev) =>\n prev.map((m) => (m.id === updatedMessage.id ? updatedMessage : m)),\n );\n break;\n }\n case \"message.deleted\": {\n const { message_id } = data.payload as { message_id: string };\n setMessages((prev) =>\n prev.map((m) =>\n m.id === message_id ? { ...m, deleted: true } : m,\n ),\n );\n break;\n }\n case \"message.delivered\":\n case \"message.read\": {\n const { message_id, channel_id, status } = data.payload as {\n message_id: string;\n channel_id: string;\n status: string;\n };\n if (channel_id === currentActiveChannelId) {\n setMessages((prev) =>\n prev.map((m) =>\n m.id === message_id\n ? {\n ...m,\n status: (status as Message[\"status\"]) || \"delivered\",\n }\n : m,\n ),\n );\n }\n break;\n }\n case \"message.delivered.batch\":\n case \"message.read.batch\": {\n const { channel_id } = data.payload as { channel_id: string };\n if (channel_id === currentActiveChannelId) {\n setMessages((prev) =>\n prev.map((m) =>\n m.status === \"sent\" || m.status === \"delivered\"\n ? {\n ...m,\n status:\n data.type === \"message.delivered.batch\"\n ? \"delivered\"\n : \"read\",\n }\n : m,\n ),\n );\n }\n break;\n }\n case \"typing.start\": {\n const { channel_id, user } = data.payload as {\n channel_id: string;\n user: UserSummary;\n };\n const typingUser: TypingUser = {\n id: user.id,\n displayName: user.display_name,\n avatarUrl: user.avatar_url,\n startedAt: Date.now(),\n };\n setTypingUsers((prev) => ({\n ...prev,\n [channel_id]: [\n ...(prev[channel_id] || []).filter((u) => u.id !== user.id),\n typingUser,\n ],\n }));\n onTypingRef.current?.(channel_id, typingUser);\n break;\n }\n case \"typing.stop\": {\n const { channel_id, user_id } = data.payload as {\n channel_id: string;\n user_id: string;\n };\n setTypingUsers((prev) => ({\n ...prev,\n [channel_id]: (prev[channel_id] || []).filter(\n (u) => u.id !== user_id,\n ),\n }));\n break;\n }\n case \"pong\":\n break;\n default:\n console.log(\"[AegisChat] Unhandled message type:\", data.type);\n }\n },\n [],\n );\n\n const connectWebSocket = useCallback(() => {\n const currentSession = sessionRef.current;\n if (!currentSession?.websocket_url || !currentSession?.access_token) {\n console.warn(\n \"[AegisChat] Cannot connect WebSocket - missing session or token\",\n );\n return;\n }\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n console.log(\"[AegisChat] WebSocket already open, skipping connection\");\n return;\n }\n\n setIsConnecting(true);\n isManualDisconnect.current = false;\n\n const wsUrl = `${currentSession.websocket_url}?token=${currentSession.access_token}`;\n console.log(\"[AegisChat] Creating WebSocket connection to:\", wsUrl);\n const ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n console.log(\"[AegisChat] WebSocket connected\");\n setIsConnected(true);\n setIsConnecting(false);\n reconnectAttempts.current = 0;\n onConnectionChangeRef.current?.(true);\n\n pingInterval.current = setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: \"ping\" }));\n }\n }, PING_INTERVAL);\n\n if (activeChannelIdRef.current) {\n ws.send(\n JSON.stringify({\n type: \"channel.join\",\n payload: { channel_id: activeChannelIdRef.current },\n }),\n );\n }\n };\n\n ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n handleWebSocketMessage(data);\n } catch (error) {\n console.error(\"[AegisChat] Failed to parse WebSocket message:\", error);\n }\n };\n\n ws.onclose = () => {\n console.log(\"[AegisChat] WebSocket disconnected\");\n setIsConnected(false);\n setIsConnecting(false);\n clearTimers();\n onConnectionChangeRef.current?.(false);\n\n if (\n !isManualDisconnect.current &&\n reconnectAttempts.current < MAX_RECONNECT_ATTEMPTS\n ) {\n const delay = Math.min(\n RECONNECT_INTERVAL * Math.pow(2, reconnectAttempts.current),\n MAX_RECONNECT_DELAY,\n );\n console.log(`[AegisChat] Reconnecting in ${delay}ms...`);\n reconnectTimeout.current = setTimeout(() => {\n reconnectAttempts.current++;\n connectWebSocket();\n }, delay);\n }\n };\n\n ws.onerror = (error) => {\n console.error(\"[AegisChat] WebSocket error:\", error);\n };\n\n wsRef.current = ws;\n }, [clearTimers, handleWebSocketMessage]);\n\n const connect = useCallback(async () => {\n console.log(\"[AegisChat] connect() called\");\n const targetSession = sessionRef.current;\n if (!targetSession) {\n console.log(\"[AegisChat] No session available, skipping connect\");\n return;\n }\n if (!autoConnectRef.current) {\n console.log(\"[AegisChat] autoConnect is false, skipping connect\");\n return;\n }\n connectWebSocket();\n }, [connectWebSocket]);\n\n const disconnect = useCallback(() => {\n isManualDisconnect.current = true;\n clearTimers();\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n setIsConnected(false);\n setSession(null);\n setChannels([]);\n setMessages([]);\n }, [clearTimers]);\n\n const refreshChannels = useCallback(async () => {\n const currentSession = sessionRef.current;\n if (!currentSession) return;\n\n setIsLoadingChannels(true);\n try {\n const response = await fetchFromComms<{ channels: ChannelListItem[] }>('/channels');\n setChannels(response.channels || []);\n } catch (error) {\n console.error(\"[AegisChat] Failed to fetch channels:\", error);\n } finally {\n setIsLoadingChannels(false);\n }\n }, []);\n\n const selectChannel = useCallback(\n async (channelId: string) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n setActiveChannelId(channelId);\n setMessages([]);\n setHasMoreMessages(true);\n oldestMessageId.current = null;\n\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n if (currentActiveChannelId) {\n wsRef.current.send(\n JSON.stringify({\n type: \"channel.leave\",\n payload: { channel_id: currentActiveChannelId },\n }),\n );\n }\n wsRef.current.send(\n JSON.stringify({\n type: \"channel.join\",\n payload: { channel_id: channelId },\n }),\n );\n }\n\n setIsLoadingMessages(true);\n try {\n const response = await fetchFromComms<MessagesResponse>(\n `/channels/${channelId}/messages?limit=50`,\n );\n setMessages(response.messages || []);\n setHasMoreMessages(response.has_more);\n if (response.oldest_id) {\n oldestMessageId.current = response.oldest_id;\n }\n\n await markAsRead(channelId);\n\n setChannels((prev) =>\n prev.map((ch) =>\n ch.id === channelId ? { ...ch, unread_count: 0 } : ch,\n ),\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to load messages:\", error);\n setMessages([]);\n } finally {\n setIsLoadingMessages(false);\n }\n },\n [setActiveChannelId, fetchFromComms],\n );\n\n const markAsRead = useCallback(\n async (channelId: string) => {\n try {\n await fetchFromComms(`/channels/${channelId}/read`, { method: \"POST\" });\n } catch (error) {\n console.error(\"[AegisChat] Failed to mark as read:\", error);\n }\n },\n [fetchFromComms],\n );\n\n const loadMoreMessages = useCallback(async () => {\n if (!activeChannelId || !hasMoreMessages || isLoadingMessages) return;\n\n setIsLoadingMessages(true);\n try {\n const params = oldestMessageId.current\n ? `?before=${oldestMessageId.current}&limit=50`\n : \"?limit=50\";\n const response = await fetchFromComms<MessagesResponse>(\n `/channels/${activeChannelId}/messages${params}`,\n );\n setMessages((prev) => [...(response.messages || []), ...prev]);\n setHasMoreMessages(response.has_more);\n if (response.oldest_id) {\n oldestMessageId.current = response.oldest_id;\n }\n } catch (error) {\n console.error(\"[AegisChat] Failed to load more messages:\", error);\n } finally {\n setIsLoadingMessages(false);\n }\n }, [activeChannelId, hasMoreMessages, isLoadingMessages, fetchFromComms]);\n\n const sendMessage = useCallback(\n async (\n content: string,\n msgOptions: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n } = {},\n ) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n const currentSession = sessionRef.current;\n if (!currentActiveChannelId || !content.trim() || !currentSession) return;\n\n const tempId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const trimmedContent = content.trim();\n\n const optimisticMessage: Message = {\n id: tempId,\n tempId,\n channel_id: currentActiveChannelId,\n sender_id: currentSession.comms_user_id,\n content: trimmedContent,\n type: (msgOptions.type as Message[\"type\"]) || \"text\",\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n status: \"sending\",\n metadata: msgOptions.metadata || {},\n };\n\n setMessages((prev) => [...prev, optimisticMessage]);\n\n const now = new Date().toISOString();\n setChannels((prev) => {\n const updated = prev.map((ch) =>\n ch.id === currentActiveChannelId\n ? {\n ...ch,\n last_message: {\n id: tempId,\n content: trimmedContent,\n created_at: now,\n sender: {\n id: currentSession.comms_user_id,\n display_name: \"You\",\n status: \"online\" as const,\n },\n },\n }\n : ch,\n );\n return updated.sort((a, b) => {\n const timeA = a.last_message?.created_at || \"\";\n const timeB = b.last_message?.created_at || \"\";\n return timeB.localeCompare(timeA);\n });\n });\n\n try {\n await fetchFromComms<Message>(\n `/channels/${currentActiveChannelId}/messages`,\n {\n method: \"POST\",\n body: JSON.stringify({\n content: trimmedContent,\n type: msgOptions.type || \"text\",\n parent_id: msgOptions.parent_id,\n metadata: msgOptions.metadata,\n }),\n },\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to send message:\", error);\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? {\n ...m,\n status: \"failed\",\n errorMessage:\n error instanceof Error ? error.message : \"Failed to send\",\n }\n : m,\n ),\n );\n throw error;\n }\n },\n [fetchFromComms],\n );\n\n const uploadFile = useCallback(\n async (file: File): Promise<FileAttachment | null> => {\n const currentSession = sessionRef.current;\n if (!currentSession) return null;\n\n const fileId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n setUploadProgress((prev) => [\n ...prev,\n { fileId, fileName: file.name, progress: 0, status: \"pending\" },\n ]);\n\n try {\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === fileId\n ? { ...p, status: \"uploading\", progress: 10 }\n : p,\n ),\n );\n\n const uploadUrlResponse = await fetchFromComms<{\n upload_url: string;\n file_id: string;\n expires_at: string;\n }>(\"/files/upload-url\", {\n method: \"POST\",\n body: JSON.stringify({\n file_name: file.name,\n file_type: file.type || \"application/octet-stream\",\n file_size: file.size,\n }),\n });\n\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === fileId\n ? { ...p, fileId: uploadUrlResponse.file_id, progress: 30 }\n : p,\n ),\n );\n\n const uploadResponse = await fetch(uploadUrlResponse.upload_url, {\n method: \"PUT\",\n body: file,\n headers: { \"Content-Type\": file.type || \"application/octet-stream\" },\n });\n\n if (!uploadResponse.ok)\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === uploadUrlResponse.file_id\n ? { ...p, status: \"confirming\", progress: 70 }\n : p,\n ),\n );\n\n const confirmResponse = await fetchFromComms<{ file: FileAttachment }>(\n \"/files\",\n {\n method: \"POST\",\n body: JSON.stringify({ file_id: uploadUrlResponse.file_id }),\n },\n );\n\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === uploadUrlResponse.file_id\n ? { ...p, status: \"complete\", progress: 100 }\n : p,\n ),\n );\n setTimeout(\n () =>\n setUploadProgress((prev) =>\n prev.filter((p) => p.fileId !== uploadUrlResponse.file_id),\n ),\n 2000,\n );\n\n return confirmResponse.file;\n } catch (error) {\n console.error(\"[AegisChat] Failed to upload file:\", error);\n setUploadProgress((prev) =>\n prev.map((p) =>\n p.fileId === fileId\n ? {\n ...p,\n status: \"error\",\n error:\n error instanceof Error ? error.message : \"Upload failed\",\n }\n : p,\n ),\n );\n setTimeout(\n () =>\n setUploadProgress((prev) =>\n prev.filter((p) => p.fileId !== fileId),\n ),\n 5000,\n );\n return null;\n }\n },\n [fetchFromComms],\n );\n\n const sendMessageWithFiles = useCallback(\n async (\n content: string,\n files: File[],\n msgOptions: {\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n } = {},\n ) => {\n const currentActiveChannelId = activeChannelIdRef.current;\n const currentSession = sessionRef.current;\n if (\n !currentActiveChannelId ||\n (!content.trim() && files.length === 0) ||\n !currentSession\n )\n return;\n\n const tempId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const trimmedContent = content.trim();\n\n const optimisticMessage: Message = {\n id: tempId,\n tempId,\n channel_id: currentActiveChannelId,\n sender_id: currentSession.comms_user_id,\n content: trimmedContent || `Uploading ${files.length} file(s)...`,\n type: \"file\",\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n status: \"sending\",\n metadata: {\n ...msgOptions.metadata,\n files: files.map((f) => ({\n id: `temp-${f.name}`,\n filename: f.name,\n mime_type: f.type,\n size: f.size,\n url: \"\",\n })),\n },\n };\n\n setMessages((prev) => [...prev, optimisticMessage]);\n\n try {\n const uploadedFiles: FileAttachment[] = [];\n for (const file of files) {\n const attachment = await uploadFile(file);\n if (attachment) uploadedFiles.push(attachment);\n }\n\n const messageType =\n uploadedFiles.length > 0 && !trimmedContent ? \"file\" : \"text\";\n\n await fetchFromComms<Message>(\n `/channels/${currentActiveChannelId}/messages`,\n {\n method: \"POST\",\n body: JSON.stringify({\n content:\n trimmedContent ||\n (uploadedFiles.length > 0\n ? `Shared ${uploadedFiles.length} file(s)`\n : \"\"),\n type: msgOptions.type || messageType,\n parent_id: msgOptions.parent_id,\n metadata: { ...msgOptions.metadata, files: uploadedFiles },\n file_ids: uploadedFiles.map((f) => f.id),\n }),\n },\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to send message with files:\", error);\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? {\n ...m,\n status: \"failed\",\n errorMessage:\n error instanceof Error ? error.message : \"Failed to send\",\n }\n : m,\n ),\n );\n throw error;\n }\n },\n [fetchFromComms, uploadFile],\n );\n\n const stopTyping = useCallback(() => {\n const currentActiveChannelId = activeChannelIdRef.current;\n if (!currentActiveChannelId || !wsRef.current) return;\n wsRef.current.send(\n JSON.stringify({\n type: \"typing.stop\",\n payload: { channel_id: currentActiveChannelId },\n }),\n );\n if (typingTimeout.current) {\n clearTimeout(typingTimeout.current);\n typingTimeout.current = null;\n }\n }, []);\n\n const startTyping = useCallback(() => {\n const currentActiveChannelId = activeChannelIdRef.current;\n if (!currentActiveChannelId || !wsRef.current) return;\n wsRef.current.send(\n JSON.stringify({\n type: \"typing.start\",\n payload: { channel_id: currentActiveChannelId },\n }),\n );\n if (typingTimeout.current) clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(stopTyping, TYPING_TIMEOUT);\n }, [stopTyping]);\n\n const createDMWithUser = useCallback(\n async (userId: string): Promise<string | null> => {\n try {\n const channel = await fetchFromComms<{ id: string }>(\"/channels/dm\", {\n method: \"POST\",\n body: JSON.stringify({ user_id: userId }),\n });\n await refreshChannels();\n return channel.id;\n } catch (error) {\n console.error(\"[AegisChat] Failed to create DM:\", error);\n return null;\n }\n },\n [fetchFromComms, refreshChannels],\n );\n\n const retryMessage = useCallback(\n async (tempId: string) => {\n const failedMessage = messages.find(\n (m) => m.tempId === tempId && m.status === \"failed\",\n );\n const currentActiveChannelId = activeChannelIdRef.current;\n if (!failedMessage || !currentActiveChannelId) return;\n\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? { ...m, status: \"sending\", errorMessage: undefined }\n : m,\n ),\n );\n\n try {\n await fetchFromComms<Message>(\n `/channels/${currentActiveChannelId}/messages`,\n {\n method: \"POST\",\n body: JSON.stringify({\n content: failedMessage.content,\n type: failedMessage.type,\n metadata: failedMessage.metadata,\n }),\n },\n );\n } catch (error) {\n console.error(\"[AegisChat] Failed to retry message:\", error);\n setMessages((prev) =>\n prev.map((m) =>\n m.tempId === tempId\n ? {\n ...m,\n status: \"failed\",\n errorMessage:\n error instanceof Error ? error.message : \"Failed to send\",\n }\n : m,\n ),\n );\n }\n },\n [messages, fetchFromComms],\n );\n\n const deleteFailedMessage = useCallback((tempId: string) => {\n setMessages((prev) => prev.filter((m) => m.tempId !== tempId));\n }, []);\n\n const setup = useCallback((options: UseChatOptions) => {\n const {\n config,\n role,\n clientId,\n initialSession,\n autoConnect = true,\n onMessage,\n onTyping,\n onConnectionChange,\n } = options;\n\n roleRef.current = role;\n clientIdRef.current = clientId;\n autoConnectRef.current = autoConnect;\n onMessageRef.current = onMessage;\n onTypingRef.current = onTyping;\n onConnectionChangeRef.current = onConnectionChange;\n\n if (initialSession) {\n sessionRef.current = initialSession;\n\n if (!config) {\n const url = initialSession.api_url;\n const normalizedUrl = url.includes('/api/v1') || url.includes('/v')\n ? url\n : `${url}/api/v1`;\n configureApiClient({\n baseUrl: normalizedUrl,\n getAccessToken: async () => sessionRef.current?.access_token || \"\",\n });\n }\n\n setSession(initialSession);\n }\n }, []);\n\n useEffect(() => {\n if (session && !isConnected && !isConnecting && autoConnectRef.current) {\n connectWebSocket();\n }\n }, [session, isConnected, isConnecting, connectWebSocket]);\n\n useEffect(() => {\n if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {\n wsRef.current.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n handleWebSocketMessage(data);\n } catch (error) {\n console.error(\n \"[AegisChat] Failed to parse WebSocket message:\",\n error,\n );\n }\n };\n }\n }, [handleWebSocketMessage]);\n\n useEffect(() => {\n if (isConnected && channels.length === 0) {\n refreshChannels();\n }\n }, [isConnected, channels.length, refreshChannels]);\n\n useEffect(() => {\n const storedActiveChannel = getActiveChannelId();\n if (storedActiveChannel && !activeChannelId) {\n selectChannel(storedActiveChannel);\n }\n }, [getActiveChannelId, activeChannelId, selectChannel]);\n\n useEffect(() => {\n return () => {\n clearTimers();\n if (typingTimeout.current) clearTimeout(typingTimeout.current);\n if (wsRef.current) {\n isManualDisconnect.current = true;\n wsRef.current.close();\n wsRef.current = null;\n }\n };\n }, [clearTimers]);\n\n return {\n session,\n isConnected,\n isConnecting,\n channels,\n messages,\n activeChannelId,\n typingUsers: activeChannelId ? typingUsers[activeChannelId] || [] : [],\n isLoadingChannels,\n isLoadingMessages,\n hasMoreMessages,\n uploadProgress,\n connect,\n disconnect,\n selectChannel,\n sendMessage,\n sendMessageWithFiles,\n uploadFile,\n loadMoreMessages,\n startTyping,\n stopTyping,\n refreshChannels,\n createDMWithUser,\n retryMessage,\n deleteFailedMessage,\n markAsRead,\n setup,\n };\n}\n\nexport default useChat;\n","// ============================================================================\n// AegisChat React SDK - API Service\n// ============================================================================\n\nimport type {\n ApiResponse,\n ChatSession,\n ChatConnectParams,\n Channel,\n ChannelListItem,\n Message,\n MessagesResponse,\n UserSummary,\n ReactionSummary,\n FileAttachment,\n UploadUrlResponse,\n} from \"../types\";\n\nlet baseUrl = \"\";\nlet getAccessToken: () => Promise<string> | string = () => \"\";\nlet onUnauthorized: (() => void) | undefined;\n\nexport function configureApiClient(config: {\n baseUrl: string;\n getAccessToken: () => Promise<string> | string;\n onUnauthorized?: () => void;\n}): void {\n baseUrl = config.baseUrl;\n getAccessToken = config.getAccessToken;\n onUnauthorized = config.onUnauthorized;\n}\n\nasync function fetchWithAuth<T>(\n path: string,\n options: RequestInit = {},\n): Promise<T> {\n const token = await (typeof getAccessToken === \"function\"\n ? getAccessToken()\n : getAccessToken);\n\n const response = await fetch(`${baseUrl}${path}`, {\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n ...options.headers,\n },\n });\n\n if (response.status === 401) {\n onUnauthorized?.();\n throw new Error(\"Unauthorized\");\n }\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n return response.json();\n}\n\nexport const chatApi = {\n /**\n * Connect to chat session\n */\n async connect(\n params: ChatConnectParams,\n signal?: AbortSignal,\n ): Promise<ApiResponse<ChatSession>> {\n return fetchWithAuth(\"/chat/connect\", {\n method: \"POST\",\n body: JSON.stringify(params),\n signal,\n });\n },\n\n /**\n * Refresh access token\n */\n async refreshToken(\n refreshToken: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ access_token: string; expires_in: number }>> {\n return fetchWithAuth(\"/chat/refresh\", {\n method: \"POST\",\n body: JSON.stringify({ refresh_token: refreshToken }),\n signal,\n });\n },\n};\n\nexport const channelsApi = {\n /**\n * List channels\n */\n async list(\n options: { type?: string; limit?: number } = {},\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ channels: ChannelListItem[] }>> {\n const params = new URLSearchParams();\n if (options.type) params.append(\"type\", options.type);\n if (options.limit) params.append(\"limit\", String(options.limit));\n const query = params.toString() ? `?${params.toString()}` : \"\";\n return fetchWithAuth(`/channels${query}`, { signal });\n },\n\n /**\n * Get channel by ID\n */\n async get(\n channelId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<Channel>> {\n return fetchWithAuth(`/channels/${channelId}`, { signal });\n },\n\n /**\n * Get or create DM channel\n */\n async getOrCreateDM(\n userId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<Channel>> {\n return fetchWithAuth(\"/channels/dm\", {\n method: \"POST\",\n body: JSON.stringify({ user_id: userId }),\n signal,\n });\n },\n\n /**\n * Create channel\n */\n async create(\n data: {\n name: string;\n type?: string;\n description?: string;\n metadata?: Record<string, unknown>;\n },\n signal?: AbortSignal,\n ): Promise<ApiResponse<Channel>> {\n return fetchWithAuth(\"/api/v1/channels\", {\n method: \"POST\",\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Mark channel as read\n */\n async markAsRead(\n channelId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ unread_count: number }>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}/read`, {\n method: \"POST\",\n signal,\n });\n },\n\n /**\n * Get channel members\n */\n async getMembers(\n channelId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ members: UserSummary[] }>> {\n return fetchWithAuth(`/channels/${channelId}/members`, { signal });\n },\n\n /**\n * Update channel\n */\n async update(\n channelId: string,\n data: {\n name?: string;\n description?: string;\n metadata?: Record<string, unknown>;\n },\n signal?: AbortSignal,\n ): Promise<ApiResponse<Channel>> {\n return fetchWithAuth(`/api/v1/channels/${channelId}`, {\n method: \"PATCH\",\n body: JSON.stringify(data),\n signal,\n });\n },\n};\n\nexport const messagesApi = {\n /**\n * List messages in a channel\n */\n async list(\n channelId: string,\n options: { limit?: number; before?: string } = {},\n signal?: AbortSignal,\n ): Promise<ApiResponse<MessagesResponse>> {\n const params = new URLSearchParams();\n if (options.limit) params.append(\"limit\", String(options.limit));\n if (options.before) params.append(\"before\", options.before);\n const query = params.toString() ? `?${params.toString()}` : \"\";\n return fetchWithAuth(`/channels/${channelId}/messages${query}`, {\n signal,\n });\n },\n\n /**\n * Send a message\n */\n async send(\n channelId: string,\n data: {\n content: string;\n type?: string;\n parent_id?: string;\n metadata?: Record<string, unknown>;\n file_ids?: string[];\n },\n signal?: AbortSignal,\n ): Promise<ApiResponse<Message>> {\n return fetchWithAuth(`/channels/${channelId}/messages`, {\n method: \"POST\",\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Update a message\n */\n async update(\n channelId: string,\n messageId: string,\n data: { content?: string; metadata?: Record<string, unknown> },\n signal?: AbortSignal,\n ): Promise<ApiResponse<Message>> {\n return fetchWithAuth(`/channels/${channelId}/messages/${messageId}`, {\n method: \"PATCH\",\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Delete a message\n */\n async delete(\n channelId: string,\n messageId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ success: boolean }>> {\n return fetchWithAuth(`/channels/${channelId}/messages/${messageId}`, {\n method: \"DELETE\",\n signal,\n });\n },\n\n /**\n * Mark messages as delivered\n */\n async markDelivered(\n channelId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ success: boolean }>> {\n return fetchWithAuth(`/channels/${channelId}/messages/delivered`, {\n method: \"POST\",\n signal,\n });\n },\n\n /**\n * Mark messages as read\n */\n async markRead(\n channelId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ success: boolean }>> {\n return fetchWithAuth(`/channels/${channelId}/messages/read`, {\n method: \"POST\",\n signal,\n });\n },\n};\n\nexport const reactionsApi = {\n /**\n * Add reaction to a message\n */\n async add(\n channelId: string,\n messageId: string,\n emoji: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ reactions: ReactionSummary[] }>> {\n return fetchWithAuth(\n `/channels/${channelId}/messages/${messageId}/reactions`,\n {\n method: \"POST\",\n body: JSON.stringify({ emoji }),\n signal,\n },\n );\n },\n\n /**\n * Remove reaction from a message\n */\n async remove(\n channelId: string,\n messageId: string,\n emoji: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ reactions: ReactionSummary[] }>> {\n return fetchWithAuth(\n `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`,\n { method: \"DELETE\", signal },\n );\n },\n};\n\nexport const filesApi = {\n /**\n * Get upload URL\n */\n async getUploadUrl(\n data: { file_name: string; file_type: string; file_size: number },\n signal?: AbortSignal,\n ): Promise<ApiResponse<UploadUrlResponse>> {\n return fetchWithAuth(\"/files/upload-url\", {\n method: \"POST\",\n body: JSON.stringify(data),\n signal,\n });\n },\n\n /**\n * Confirm file upload\n */\n async confirm(\n fileId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ file: FileAttachment }>> {\n return fetchWithAuth(\"/files\", {\n method: \"POST\",\n body: JSON.stringify({ file_id: fileId }),\n signal,\n });\n },\n\n /**\n * Get download URL\n */\n async getDownloadUrl(\n fileId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ url: string; expires_at: string }>> {\n return fetchWithAuth(`/files/${fileId}/download`, { signal });\n },\n};\n\nexport const usersApi = {\n /**\n * Search users\n */\n async search(\n query: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<{ users: UserSummary[] }>> {\n return fetchWithAuth(`/users/search?q=${encodeURIComponent(query)}`, {\n signal,\n });\n },\n\n /**\n * Get user by ID\n */\n async get(\n userId: string,\n signal?: AbortSignal,\n ): Promise<ApiResponse<UserSummary>> {\n return fetchWithAuth(`/users/${userId}`, { signal });\n },\n};\n\nexport default {\n chatApi,\n channelsApi,\n messagesApi,\n reactionsApi,\n filesApi,\n usersApi,\n configureApiClient,\n};\n","// ============================================================================\n// AegisChat React SDK - useAutoRead Hook\n// ============================================================================\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { channelsApi } from '../services/api';\n\nconst SESSION_STORAGE_KEY = '@aegischat/activeChannel';\n\nexport interface UseAutoReadOptions {\n onMarkAsRead?: (channelId: string) => void;\n}\n\nexport interface UseAutoReadReturn {\n markAsRead: (channelId: string) => Promise<void>;\n markAllAsRead: () => Promise<void>;\n isFocused: boolean;\n}\n\nexport function useAutoRead(options: UseAutoReadOptions = {}): UseAutoReadReturn {\n const [isFocused, setIsFocused] = useState(false);\n\n useEffect(() => {\n setIsFocused(typeof document !== 'undefined' && document.hasFocus());\n\n const handleFocus = () => setIsFocused(true);\n const handleBlur = () => setIsFocused(false);\n\n window.addEventListener('focus', handleFocus);\n window.addEventListener('blur', handleBlur);\n\n return () => {\n window.removeEventListener('focus', handleFocus);\n window.removeEventListener('blur', handleBlur);\n };\n }, []);\n\n useEffect(() => {\n const handleVisibilityChange = () => {\n if (!document.hidden) {\n const activeChannelId = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (activeChannelId) {\n markAsRead(activeChannelId);\n }\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => document.removeEventListener('visibilitychange', handleVisibilityChange);\n }, []);\n\n const markAsRead = useCallback(async (channelId: string) => {\n if (!isFocused) return;\n try {\n await channelsApi.markAsRead(channelId);\n options.onMarkAsRead?.(channelId);\n } catch (error) {\n console.error('[AegisChat] useAutoRead: Failed to mark as read:', error);\n }\n }, [isFocused, options.onMarkAsRead]);\n\n const markAllAsRead = useCallback(async () => {\n if (!isFocused) return;\n try {\n const response = await channelsApi.list({});\n const channels = response.data.channels || [];\n await Promise.all(\n channels.filter((ch) => ch.unread_count > 0).map((ch) => channelsApi.markAsRead(ch.id))\n );\n } catch (error) {\n console.error('[AegisChat] useAutoRead: Failed to mark all as read:', error);\n }\n }, [isFocused]);\n\n return { markAsRead, markAllAsRead, isFocused };\n}\n\nexport default useAutoRead;\n","// ============================================================================\n// AegisChat React SDK - useChannels Hook\n// ============================================================================\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { channelsApi } from '../services/api';\nimport type { ChannelListItem, Channel } from '../types';\n\nexport interface UseChannelsOptions {\n type?: 'direct' | 'public' | 'private';\n limit?: number;\n autoFetch?: boolean;\n onChannelCreated?: (channel: Channel) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface UseChannelsReturn {\n channels: ChannelListItem[];\n isLoading: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n getOrCreateDM: (userId: string) => Promise<Channel>;\n markAsRead: (channelId: string) => Promise<void>;\n}\n\nexport function useChannels(options: UseChannelsOptions = {}): UseChannelsReturn {\n const { type, limit = 20, autoFetch = true, onChannelCreated, onError } = options;\n\n const [channels, setChannels] = useState<ChannelListItem[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const fetchChannels = useCallback(async (signal?: AbortSignal) => {\n setIsLoading(true);\n setError(null);\n\n try {\n const response = await channelsApi.list({ type, limit }, signal);\n if (signal?.aborted) return;\n setChannels(response.data.channels);\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') return;\n const error = err instanceof Error ? err : new Error('Failed to fetch channels');\n setError(error);\n onError?.(error);\n } finally {\n if (!signal?.aborted) setIsLoading(false);\n }\n }, [type, limit, onError]);\n\n const refetch = useCallback(async () => {\n if (abortControllerRef.current) abortControllerRef.current.abort();\n const controller = new AbortController();\n abortControllerRef.current = controller;\n await fetchChannels(controller.signal);\n }, [fetchChannels]);\n\n const getOrCreateDM = useCallback(async (userId: string): Promise<Channel> => {\n try {\n const response = await channelsApi.getOrCreateDM(userId);\n if (abortControllerRef.current) abortControllerRef.current.abort();\n const controller = new AbortController();\n abortControllerRef.current = controller;\n fetchChannels(controller.signal);\n onChannelCreated?.(response.data);\n return response.data;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to create DM');\n onError?.(error);\n throw error;\n }\n }, [fetchChannels, onChannelCreated, onError]);\n\n const markAsRead = useCallback(async (channelId: string): Promise<void> => {\n try {\n await channelsApi.markAsRead(channelId);\n setChannels((prev) => prev.map((ch) => ch.id === channelId ? { ...ch, unread_count: 0 } : ch));\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to mark as read');\n onError?.(error);\n throw error;\n }\n }, [onError]);\n\n useEffect(() => {\n if (autoFetch) {\n if (abortControllerRef.current) abortControllerRef.current.abort();\n const controller = new AbortController();\n abortControllerRef.current = controller;\n fetchChannels(controller.signal);\n return () => controller.abort();\n }\n }, [autoFetch, fetchChannels]);\n\n return { channels, isLoading, error, refetch, getOrCreateDM, markAsRead };\n}\n\nexport default useChannels;\n","// ============================================================================\n// AegisChat React SDK - useMessages Hook\n// ============================================================================\n\nimport { useCallback, useState } from 'react';\nimport { messagesApi } from '../services/api';\nimport type { Message, MessagesResponse } from '../types';\n\nexport interface UseMessagesOptions {\n channelId: string;\n}\n\nexport interface UseMessagesReturn {\n messages: Message[];\n isLoading: boolean;\n hasMore: boolean;\n sendMessage: (params: { content: string; type?: string; metadata?: Record<string, unknown> }) => Promise<void>;\n loadMore: () => Promise<void>;\n}\n\nexport function useMessages(_options: UseMessagesOptions): UseMessagesReturn {\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n\n const sendMessage = useCallback(async (params: { content: string; type?: string; metadata?: Record<string, unknown> }) => {\n // Implementation would go here\n }, []);\n\n const loadMore = useCallback(async () => {\n // Implementation would go here\n }, []);\n\n return { messages, isLoading, hasMore, sendMessage, loadMore };\n}\n\nexport default useMessages;\n","// ============================================================================\n// AegisChat React SDK - useTypingIndicator Hook\n// ============================================================================\n\nimport { useCallback, useState } from 'react';\nimport type { TypingUser } from '../types';\n\nexport interface UseTypingIndicatorOptions {\n channelId: string;\n ws?: WebSocket | null;\n}\n\nexport interface UseTypingIndicatorReturn {\n typingUsers: TypingUser[];\n startTyping: () => void;\n stopTyping: () => void;\n}\n\nexport function useTypingIndicator(_options: UseTypingIndicatorOptions): UseTypingIndicatorReturn {\n const [typingUsers, setTypingUsers] = useState<TypingUser[]>([]);\n\n const startTyping = useCallback(() => {}, []);\n const stopTyping = useCallback(() => {}, []);\n\n return { typingUsers, startTyping, stopTyping };\n}\n\nexport default useTypingIndicator;\n","// ============================================================================\n// AegisChat React SDK - useReactions Hook\n// ============================================================================\n\nimport { useState } from 'react';\nimport type { ReactionSummary } from '../types';\n\nexport interface UseReactionsOptions {\n channelId: string;\n messageId: string;\n}\n\nexport interface UseReactionsReturn {\n reactions: ReactionSummary[];\n addReaction: (emoji: string) => Promise<void>;\n removeReaction: (emoji: string) => Promise<void>;\n}\n\nexport function useReactions(_options: UseReactionsOptions): UseReactionsReturn {\n const [reactions, setReactions] = useState<ReactionSummary[]>([]);\n\n const addReaction = async (_emoji: string) => {};\n const removeReaction = async (_emoji: string) => {};\n\n return { reactions, addReaction, removeReaction };\n}\n\nexport default useReactions;\n","// ============================================================================\n// AegisChat React SDK - useFileUpload Hook\n// ============================================================================\n\nimport { useState } from 'react';\nimport type { FileAttachment, UploadProgress } from '../types';\n\nexport interface UseFileUploadOptions {\n channelId: string;\n}\n\nexport interface UseFileUploadReturn {\n uploadProgress: UploadProgress[];\n upload: (file: File) => Promise<FileAttachment | null>;\n}\n\nexport function useFileUpload(_options: UseFileUploadOptions): UseFileUploadReturn {\n const [uploadProgress, setUploadProgress] = useState<UploadProgress[]>([]);\n\n const upload = async (_file: File): Promise<FileAttachment | null> => null;\n\n return { uploadProgress, upload };\n}\n\nexport default useFileUpload;\n","// ============================================================================\n// AegisChat React SDK - useMentions Hook\n// ============================================================================\n\nexport interface UseMentionsOptions {}\n\nexport interface UseMentionsReturn {\n parseMentions: (content: string) => string[];\n highlightMentions: (content: string) => string;\n isUserMentioned: (content: string, userId: string) => boolean;\n}\n\nexport function useMentions(_options: UseMentionsOptions = {}): UseMentionsReturn {\n const parseMentions = (content: string): string[] => {\n const mentionRegex = /@\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n const mentions: string[] = [];\n let match;\n while ((match = mentionRegex.exec(content)) !== null) {\n mentions.push(match[2]);\n }\n return mentions;\n };\n\n const highlightMentions = (content: string): string => {\n return content.replace(/@\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<span class=\"mention\">@$1</span>');\n };\n\n const isUserMentioned = (content: string, userId: string): boolean => {\n const mentions = parseMentions(content);\n return mentions.includes(userId);\n };\n\n return { parseMentions, highlightMentions, isUserMentioned };\n}\n\nexport default useMentions;\n"],"mappings":"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","names":["options","config","role","clientId","initialSession","autoConnect","onMessage","onTyping","onConnectionChange","import_react","SESSION_STORAGE_KEY","import_react","error","import_react","import_react","import_react","import_react"]}