@antzsoft/chat-core 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -25,6 +25,7 @@ interface UploadableFile {
25
25
  }
26
26
  interface User {
27
27
  id: string;
28
+ externalId?: string;
28
29
  tenantId: string;
29
30
  email: string;
30
31
  username: string;
@@ -172,6 +173,38 @@ interface Conversation {
172
173
  isEncryptionEnabled?: boolean;
173
174
  encryptionKey?: string;
174
175
  }
176
+ interface ConversationUnreadCount {
177
+ conversationId: string;
178
+ unreadCount: number;
179
+ }
180
+ interface UnreadSummary {
181
+ /** Total unread messages across all conversations */
182
+ totalUnread: number;
183
+ /** Per-conversation breakdown — only includes conversations with unread > 0 */
184
+ byConversation: ConversationUnreadCount[];
185
+ }
186
+ interface ConversationListParams {
187
+ page?: number;
188
+ limit?: number;
189
+ /** Filter by conversation type */
190
+ type?: ConversationType;
191
+ /** Only pinned (true) or unpinned (false) conversations */
192
+ isPinned?: boolean;
193
+ /** Only muted (true) or unmuted (false) conversations */
194
+ isMuted?: boolean;
195
+ /** Only conversations with unread messages */
196
+ hasUnread?: boolean;
197
+ /** Search by group name / description (text index) */
198
+ search?: string;
199
+ /** Filter by current user's role in the conversation */
200
+ role?: ParticipantRole;
201
+ /** Filter by whether the last message has attachments */
202
+ hasAttachments?: boolean;
203
+ /** Filter by last message attachment type */
204
+ attachmentType?: FileType;
205
+ /** Filter by notification setting */
206
+ notificationsEnabled?: boolean;
207
+ }
175
208
  interface PaginationMeta {
176
209
  total: number;
177
210
  page: number;
@@ -326,6 +359,37 @@ interface SendMessagePayload {
326
359
  encryptedContent?: EncryptedContent;
327
360
  isEncrypted?: boolean;
328
361
  }
362
+ interface QuietHours {
363
+ enabled: boolean;
364
+ /** HH:MM — e.g. "22:00" */
365
+ start: string;
366
+ /** HH:MM — e.g. "08:00" */
367
+ end: string;
368
+ /** IANA timezone — e.g. "Asia/Kolkata" */
369
+ timezone: string;
370
+ }
371
+ /**
372
+ * User notification preferences stored in chat_user_prefs.
373
+ * All fields are optional on update — only send what changed.
374
+ * Any future preference field is added here and to the server schema;
375
+ * no new collections or API endpoints needed.
376
+ */
377
+ interface UserPreferences {
378
+ /** Master switch — false disables all push notifications */
379
+ notificationsEnabled?: boolean;
380
+ /** Play sound with notifications */
381
+ soundEnabled?: boolean;
382
+ /** Show message text in notification body (false = show "New message" only) */
383
+ messagePreview?: boolean;
384
+ /** Notify when @mentioned in a group */
385
+ notifyOnMention?: boolean;
386
+ /** Notify when someone reacts to your message */
387
+ notifyOnReaction?: boolean;
388
+ /** Notify when added to a group */
389
+ notifyOnGroupInvite?: boolean;
390
+ /** Quiet hours window — no push delivered during this period */
391
+ quietHours?: QuietHours;
392
+ }
329
393
 
330
394
  interface FileSizeLimits {
331
395
  image?: number;
@@ -406,6 +470,21 @@ interface AntzChatConfig {
406
470
  /** Must match server ENCRYPTION_MODE env var. Default: 'none' */
407
471
  encryptionMode?: 'none' | 'server';
408
472
  upload?: UploadConfig;
473
+ /**
474
+ * Number of messages fetched per page when loading chat history.
475
+ * Default: 40
476
+ */
477
+ messagePageSize?: number;
478
+ /**
479
+ * Number of starred messages fetched per page.
480
+ * Default: 30
481
+ */
482
+ starredMessagePageSize?: number;
483
+ /**
484
+ * Number of search results fetched per request.
485
+ * Default: 50
486
+ */
487
+ searchPageSize?: number;
409
488
  /**
410
489
  * Platform-specific binary upload implementation.
411
490
  * Required — each SDK (web, RN) provides its own.
@@ -447,6 +526,9 @@ interface ResolvedConfig {
447
526
  };
448
527
  platformUploadFn: PlatformUploadFn;
449
528
  persistStorage: PersistStorage;
529
+ messagePageSize: number;
530
+ starredMessagePageSize: number;
531
+ searchPageSize: number;
450
532
  }
451
533
  declare function resolveConfig(config: AntzChatConfig): ResolvedConfig;
452
534
 
@@ -503,6 +585,10 @@ declare const messagesApi: {
503
585
  conversationId?: string;
504
586
  }): Promise<PaginatedResponse<Message>>;
505
587
  search(params: SearchParams): Promise<PaginatedResponse<Message>>;
588
+ getLastRead(conversationId: string): Promise<{
589
+ lastReadMessageId: string | null;
590
+ lastReadAt: string | null;
591
+ }>;
506
592
  markAsRead(conversationId: string, messageId?: string): Promise<void>;
507
593
  pin(messageId: string): Promise<Message>;
508
594
  unpin(messageId: string): Promise<Message>;
@@ -525,10 +611,7 @@ interface UpdateConversationData {
525
611
  icon?: string;
526
612
  }
527
613
  declare const conversationsApi: {
528
- list(params?: {
529
- page?: number;
530
- limit?: number;
531
- }): Promise<PaginatedResponse<Conversation>>;
614
+ list(params?: ConversationListParams): Promise<PaginatedResponse<Conversation>>;
532
615
  get(conversationId: string): Promise<Conversation>;
533
616
  createGroup(payload: CreateGroupData): Promise<Conversation>;
534
617
  createDirect(payload: CreateDirectData): Promise<Conversation>;
@@ -543,7 +626,18 @@ declare const conversationsApi: {
543
626
  unpin(conversationId: string): Promise<void>;
544
627
  leave(conversationId: string): Promise<void>;
545
628
  getMembers(conversationId: string): Promise<User[]>;
546
- searchUsers(query: string): Promise<User[]>;
629
+ /**
630
+ * Get unread message count for a single conversation.
631
+ * Use this after app foreground or socket reconnect to refresh a specific count.
632
+ */
633
+ getUnreadCount(conversationId: string): Promise<ConversationUnreadCount>;
634
+ /**
635
+ * Get total unread count across all conversations + per-conversation breakdown.
636
+ * Use on app cold start, foreground resume, or after socket reconnect.
637
+ * The socket keeps counts live while connected — this is the source of truth
638
+ * when the socket was down.
639
+ */
640
+ getUnreadSummary(): Promise<UnreadSummary>;
547
641
  };
548
642
 
549
643
  declare const storageApi: {
@@ -631,6 +725,30 @@ declare const devicesApi: {
631
725
  remove(deviceId: string): Promise<void>;
632
726
  };
633
727
 
728
+ declare const usersApi: {
729
+ list(params?: {
730
+ query?: string;
731
+ page?: number;
732
+ limit?: number;
733
+ }): Promise<PaginatedResponse<User>>;
734
+ getById(userId: string): Promise<User>;
735
+ getLastSeen(userId: string): Promise<{
736
+ lastSeenAt: string | null;
737
+ }>;
738
+ /**
739
+ * Update notification preferences for the current user.
740
+ * Partial update — only send fields you want to change.
741
+ * A prefs record is automatically created with defaults when a device
742
+ * token is first registered, so this never fails with "not found".
743
+ */
744
+ updatePreferences(prefs: UserPreferences): Promise<User>;
745
+ /**
746
+ * Fetch current notification preferences for the current user.
747
+ * Returns null if no prefs record exists yet (all defaults apply).
748
+ */
749
+ getPreferences(): Promise<UserPreferences | null>;
750
+ };
751
+
634
752
  type TokenStore = {
635
753
  getAccessToken: () => string | null | undefined;
636
754
  getRefreshToken: () => string | null | undefined;
@@ -649,7 +767,7 @@ declare function getSocket(): Socket;
649
767
  declare function tryGetSocket(): Socket | null;
650
768
  declare function getSocketStatus(): SocketStatus;
651
769
  declare function onSocketStatus(listener: StatusListener): () => void;
652
- declare function connectSocket(config: ResolvedConfig, getToken: () => string | null | undefined, userId?: string, tenantId?: string): Promise<Socket>;
770
+ declare function connectSocket(config: ResolvedConfig, getToken: () => string | null | undefined): Promise<Socket>;
653
771
  declare function disconnectSocket(): void;
654
772
  declare function reconnectSocket(token: string, userId?: string, tenantId?: string): void;
655
773
  /**
@@ -769,6 +887,10 @@ interface TypingUser {
769
887
  displayName: string;
770
888
  avatarUrl?: string;
771
889
  }
890
+ interface LastReadEntry {
891
+ messageId: string;
892
+ readAt: string;
893
+ }
772
894
  interface ChatState {
773
895
  activeConversationId: string | null;
774
896
  pendingTarget: {
@@ -777,6 +899,10 @@ interface ChatState {
777
899
  } | null;
778
900
  typingUsers: Record<string, TypingUser[]>;
779
901
  onlineUsers: string[];
902
+ /** keyed by conversationId — current user's last read pointer per conversation */
903
+ lastRead: Record<string, LastReadEntry>;
904
+ /** keyed by userId — last seen timestamp for each user */
905
+ lastSeen: Record<string, string>;
780
906
  replyingTo: Message | null;
781
907
  editingMessage: Message | null;
782
908
  isSidebarOpen: boolean;
@@ -792,6 +918,8 @@ interface ChatState {
792
918
  setUserOnline: (userId: string) => void;
793
919
  setUserOffline: (userId: string) => void;
794
920
  setOnlineUsers: (userIds: string[]) => void;
921
+ setLastRead: (conversationId: string, messageId: string, readAt: string) => void;
922
+ setLastSeen: (userId: string, lastSeenAt: string) => void;
795
923
  setReplyingTo: (message: Message | null) => void;
796
924
  setEditingMessage: (message: Message | null) => void;
797
925
  toggleSidebar: () => void;
@@ -851,16 +979,17 @@ declare class AntzChatClient {
851
979
  conversationId?: string;
852
980
  }): Promise<PaginatedResponse<Message>>;
853
981
  search(params: SearchParams): Promise<PaginatedResponse<Message>>;
982
+ getLastRead(conversationId: string): Promise<{
983
+ lastReadMessageId: string | null;
984
+ lastReadAt: string | null;
985
+ }>;
854
986
  markAsRead(conversationId: string, messageId?: string): Promise<void>;
855
987
  pin(messageId: string): Promise<Message>;
856
988
  unpin(messageId: string): Promise<Message>;
857
989
  getPinned(conversationId: string): Promise<Message[]>;
858
990
  };
859
991
  readonly conversations: {
860
- list(params?: {
861
- page?: number;
862
- limit?: number;
863
- }): Promise<PaginatedResponse<Conversation>>;
992
+ list(params?: ConversationListParams): Promise<PaginatedResponse<Conversation>>;
864
993
  get(conversationId: string): Promise<Conversation>;
865
994
  createGroup(payload: CreateGroupData): Promise<Conversation>;
866
995
  createDirect(payload: CreateDirectData): Promise<Conversation>;
@@ -875,7 +1004,8 @@ declare class AntzChatClient {
875
1004
  unpin(conversationId: string): Promise<void>;
876
1005
  leave(conversationId: string): Promise<void>;
877
1006
  getMembers(conversationId: string): Promise<User[]>;
878
- searchUsers(query: string): Promise<User[]>;
1007
+ getUnreadCount(conversationId: string): Promise<ConversationUnreadCount>;
1008
+ getUnreadSummary(): Promise<UnreadSummary>;
879
1009
  };
880
1010
  readonly storage: {
881
1011
  requestPresignedUrl(payload: PresignedUrlRequest): Promise<PresignedUrlResponse>;
@@ -903,6 +1033,19 @@ declare class AntzChatClient {
903
1033
  limit?: number;
904
1034
  }): Promise<PaginatedResponse<FileResponse>>;
905
1035
  };
1036
+ readonly users: {
1037
+ list(params?: {
1038
+ query?: string;
1039
+ page?: number;
1040
+ limit?: number;
1041
+ }): Promise<PaginatedResponse<User>>;
1042
+ getById(userId: string): Promise<User>;
1043
+ getLastSeen(userId: string): Promise<{
1044
+ lastSeenAt: string | null;
1045
+ }>;
1046
+ updatePreferences(prefs: UserPreferences): Promise<User>;
1047
+ getPreferences(): Promise<UserPreferences | null>;
1048
+ };
906
1049
  readonly socket: ClientSocketHandle;
907
1050
  constructor(rawConfig: AntzChatConfig);
908
1051
  connect(): Promise<void>;
@@ -910,4 +1053,4 @@ declare class AntzChatClient {
910
1053
  uploadFiles(files: UploadableFile[], conversationId?: string): Promise<BatchUploadResult>;
911
1054
  }
912
1055
 
913
- export { AntzChatClient, type AntzChatConfig, type Attachment, type AuthResponse, type AuthTokens, type BatchUploadResult, type Conversation, type CreateDirectData, type CreateGroupData, type CursorPaginatedResponse, type EncryptedContent, type EncryptionKeyInfo, type EncryptionMode, type FileResponse, type FileSizeLimits, type FileType, type ListMessagesParams, type LoginCredentials, type Message, type MessageAckEvent, type MessageContent, type MessageDeletedEvent, type MessageDeletedForMeEvent, type MessageDeliveredEvent, type MessageReaction, type MessageReplyReference, type MessageUpdatedEvent, type MessagesDeliveredEvent, type MobileDeviceToken, type NewMessageEvent, type OptimisticAttachment, type PaginatedResponse, type Participant, type PersistStorage, type PlatformUploadFn, type PresignedUrlRequest, type PresignedUrlResponse, type ReactionUpdatedEvent, type ReadReceiptEvent, type RegisterData, type RegisterDeviceTokenPayload, type ResolvedConfig, type ResolvedFileSizeLimits, type SearchParams, type SendData, type SendMessageAttachment, type SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TypingIndicatorEvent, type UpdateConversationData, type UploadConfig, type UploadProgress, type UploadableFile, type User, type UserStatusEvent, type WebPushDeviceToken, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveConfig, setApiClientInstance, socketEmit, storageApi, tryGetSocket, uploadBatch, useChatStore };
1056
+ export { AntzChatClient, type AntzChatConfig, type Attachment, type AuthResponse, type AuthTokens, type BatchUploadResult, type Conversation, type ConversationListParams, type ConversationUnreadCount, type CreateDirectData, type CreateGroupData, type CursorPaginatedResponse, type EncryptedContent, type EncryptionKeyInfo, type EncryptionMode, type FileResponse, type FileSizeLimits, type FileType, type LastReadEntry, type ListMessagesParams, type LoginCredentials, type Message, type MessageAckEvent, type MessageContent, type MessageDeletedEvent, type MessageDeletedForMeEvent, type MessageDeliveredEvent, type MessageReaction, type MessageReplyReference, type MessageUpdatedEvent, type MessagesDeliveredEvent, type MobileDeviceToken, type NewMessageEvent, type OptimisticAttachment, type PaginatedResponse, type Participant, type PersistStorage, type PlatformUploadFn, type PresignedUrlRequest, type PresignedUrlResponse, type QuietHours, type ReactionUpdatedEvent, type ReadReceiptEvent, type RegisterData, type RegisterDeviceTokenPayload, type ResolvedConfig, type ResolvedFileSizeLimits, type SearchParams, type SendData, type SendMessageAttachment, type SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TypingIndicatorEvent, type UnreadSummary, type UpdateConversationData, type UploadConfig, type UploadProgress, type UploadableFile, type User, type UserPreferences, type UserStatusEvent, type WebPushDeviceToken, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveConfig, setApiClientInstance, socketEmit, storageApi, tryGetSocket, uploadBatch, useChatStore, usersApi };
package/dist/index.d.ts CHANGED
@@ -25,6 +25,7 @@ interface UploadableFile {
25
25
  }
26
26
  interface User {
27
27
  id: string;
28
+ externalId?: string;
28
29
  tenantId: string;
29
30
  email: string;
30
31
  username: string;
@@ -172,6 +173,38 @@ interface Conversation {
172
173
  isEncryptionEnabled?: boolean;
173
174
  encryptionKey?: string;
174
175
  }
176
+ interface ConversationUnreadCount {
177
+ conversationId: string;
178
+ unreadCount: number;
179
+ }
180
+ interface UnreadSummary {
181
+ /** Total unread messages across all conversations */
182
+ totalUnread: number;
183
+ /** Per-conversation breakdown — only includes conversations with unread > 0 */
184
+ byConversation: ConversationUnreadCount[];
185
+ }
186
+ interface ConversationListParams {
187
+ page?: number;
188
+ limit?: number;
189
+ /** Filter by conversation type */
190
+ type?: ConversationType;
191
+ /** Only pinned (true) or unpinned (false) conversations */
192
+ isPinned?: boolean;
193
+ /** Only muted (true) or unmuted (false) conversations */
194
+ isMuted?: boolean;
195
+ /** Only conversations with unread messages */
196
+ hasUnread?: boolean;
197
+ /** Search by group name / description (text index) */
198
+ search?: string;
199
+ /** Filter by current user's role in the conversation */
200
+ role?: ParticipantRole;
201
+ /** Filter by whether the last message has attachments */
202
+ hasAttachments?: boolean;
203
+ /** Filter by last message attachment type */
204
+ attachmentType?: FileType;
205
+ /** Filter by notification setting */
206
+ notificationsEnabled?: boolean;
207
+ }
175
208
  interface PaginationMeta {
176
209
  total: number;
177
210
  page: number;
@@ -326,6 +359,37 @@ interface SendMessagePayload {
326
359
  encryptedContent?: EncryptedContent;
327
360
  isEncrypted?: boolean;
328
361
  }
362
+ interface QuietHours {
363
+ enabled: boolean;
364
+ /** HH:MM — e.g. "22:00" */
365
+ start: string;
366
+ /** HH:MM — e.g. "08:00" */
367
+ end: string;
368
+ /** IANA timezone — e.g. "Asia/Kolkata" */
369
+ timezone: string;
370
+ }
371
+ /**
372
+ * User notification preferences stored in chat_user_prefs.
373
+ * All fields are optional on update — only send what changed.
374
+ * Any future preference field is added here and to the server schema;
375
+ * no new collections or API endpoints needed.
376
+ */
377
+ interface UserPreferences {
378
+ /** Master switch — false disables all push notifications */
379
+ notificationsEnabled?: boolean;
380
+ /** Play sound with notifications */
381
+ soundEnabled?: boolean;
382
+ /** Show message text in notification body (false = show "New message" only) */
383
+ messagePreview?: boolean;
384
+ /** Notify when @mentioned in a group */
385
+ notifyOnMention?: boolean;
386
+ /** Notify when someone reacts to your message */
387
+ notifyOnReaction?: boolean;
388
+ /** Notify when added to a group */
389
+ notifyOnGroupInvite?: boolean;
390
+ /** Quiet hours window — no push delivered during this period */
391
+ quietHours?: QuietHours;
392
+ }
329
393
 
330
394
  interface FileSizeLimits {
331
395
  image?: number;
@@ -406,6 +470,21 @@ interface AntzChatConfig {
406
470
  /** Must match server ENCRYPTION_MODE env var. Default: 'none' */
407
471
  encryptionMode?: 'none' | 'server';
408
472
  upload?: UploadConfig;
473
+ /**
474
+ * Number of messages fetched per page when loading chat history.
475
+ * Default: 40
476
+ */
477
+ messagePageSize?: number;
478
+ /**
479
+ * Number of starred messages fetched per page.
480
+ * Default: 30
481
+ */
482
+ starredMessagePageSize?: number;
483
+ /**
484
+ * Number of search results fetched per request.
485
+ * Default: 50
486
+ */
487
+ searchPageSize?: number;
409
488
  /**
410
489
  * Platform-specific binary upload implementation.
411
490
  * Required — each SDK (web, RN) provides its own.
@@ -447,6 +526,9 @@ interface ResolvedConfig {
447
526
  };
448
527
  platformUploadFn: PlatformUploadFn;
449
528
  persistStorage: PersistStorage;
529
+ messagePageSize: number;
530
+ starredMessagePageSize: number;
531
+ searchPageSize: number;
450
532
  }
451
533
  declare function resolveConfig(config: AntzChatConfig): ResolvedConfig;
452
534
 
@@ -503,6 +585,10 @@ declare const messagesApi: {
503
585
  conversationId?: string;
504
586
  }): Promise<PaginatedResponse<Message>>;
505
587
  search(params: SearchParams): Promise<PaginatedResponse<Message>>;
588
+ getLastRead(conversationId: string): Promise<{
589
+ lastReadMessageId: string | null;
590
+ lastReadAt: string | null;
591
+ }>;
506
592
  markAsRead(conversationId: string, messageId?: string): Promise<void>;
507
593
  pin(messageId: string): Promise<Message>;
508
594
  unpin(messageId: string): Promise<Message>;
@@ -525,10 +611,7 @@ interface UpdateConversationData {
525
611
  icon?: string;
526
612
  }
527
613
  declare const conversationsApi: {
528
- list(params?: {
529
- page?: number;
530
- limit?: number;
531
- }): Promise<PaginatedResponse<Conversation>>;
614
+ list(params?: ConversationListParams): Promise<PaginatedResponse<Conversation>>;
532
615
  get(conversationId: string): Promise<Conversation>;
533
616
  createGroup(payload: CreateGroupData): Promise<Conversation>;
534
617
  createDirect(payload: CreateDirectData): Promise<Conversation>;
@@ -543,7 +626,18 @@ declare const conversationsApi: {
543
626
  unpin(conversationId: string): Promise<void>;
544
627
  leave(conversationId: string): Promise<void>;
545
628
  getMembers(conversationId: string): Promise<User[]>;
546
- searchUsers(query: string): Promise<User[]>;
629
+ /**
630
+ * Get unread message count for a single conversation.
631
+ * Use this after app foreground or socket reconnect to refresh a specific count.
632
+ */
633
+ getUnreadCount(conversationId: string): Promise<ConversationUnreadCount>;
634
+ /**
635
+ * Get total unread count across all conversations + per-conversation breakdown.
636
+ * Use on app cold start, foreground resume, or after socket reconnect.
637
+ * The socket keeps counts live while connected — this is the source of truth
638
+ * when the socket was down.
639
+ */
640
+ getUnreadSummary(): Promise<UnreadSummary>;
547
641
  };
548
642
 
549
643
  declare const storageApi: {
@@ -631,6 +725,30 @@ declare const devicesApi: {
631
725
  remove(deviceId: string): Promise<void>;
632
726
  };
633
727
 
728
+ declare const usersApi: {
729
+ list(params?: {
730
+ query?: string;
731
+ page?: number;
732
+ limit?: number;
733
+ }): Promise<PaginatedResponse<User>>;
734
+ getById(userId: string): Promise<User>;
735
+ getLastSeen(userId: string): Promise<{
736
+ lastSeenAt: string | null;
737
+ }>;
738
+ /**
739
+ * Update notification preferences for the current user.
740
+ * Partial update — only send fields you want to change.
741
+ * A prefs record is automatically created with defaults when a device
742
+ * token is first registered, so this never fails with "not found".
743
+ */
744
+ updatePreferences(prefs: UserPreferences): Promise<User>;
745
+ /**
746
+ * Fetch current notification preferences for the current user.
747
+ * Returns null if no prefs record exists yet (all defaults apply).
748
+ */
749
+ getPreferences(): Promise<UserPreferences | null>;
750
+ };
751
+
634
752
  type TokenStore = {
635
753
  getAccessToken: () => string | null | undefined;
636
754
  getRefreshToken: () => string | null | undefined;
@@ -649,7 +767,7 @@ declare function getSocket(): Socket;
649
767
  declare function tryGetSocket(): Socket | null;
650
768
  declare function getSocketStatus(): SocketStatus;
651
769
  declare function onSocketStatus(listener: StatusListener): () => void;
652
- declare function connectSocket(config: ResolvedConfig, getToken: () => string | null | undefined, userId?: string, tenantId?: string): Promise<Socket>;
770
+ declare function connectSocket(config: ResolvedConfig, getToken: () => string | null | undefined): Promise<Socket>;
653
771
  declare function disconnectSocket(): void;
654
772
  declare function reconnectSocket(token: string, userId?: string, tenantId?: string): void;
655
773
  /**
@@ -769,6 +887,10 @@ interface TypingUser {
769
887
  displayName: string;
770
888
  avatarUrl?: string;
771
889
  }
890
+ interface LastReadEntry {
891
+ messageId: string;
892
+ readAt: string;
893
+ }
772
894
  interface ChatState {
773
895
  activeConversationId: string | null;
774
896
  pendingTarget: {
@@ -777,6 +899,10 @@ interface ChatState {
777
899
  } | null;
778
900
  typingUsers: Record<string, TypingUser[]>;
779
901
  onlineUsers: string[];
902
+ /** keyed by conversationId — current user's last read pointer per conversation */
903
+ lastRead: Record<string, LastReadEntry>;
904
+ /** keyed by userId — last seen timestamp for each user */
905
+ lastSeen: Record<string, string>;
780
906
  replyingTo: Message | null;
781
907
  editingMessage: Message | null;
782
908
  isSidebarOpen: boolean;
@@ -792,6 +918,8 @@ interface ChatState {
792
918
  setUserOnline: (userId: string) => void;
793
919
  setUserOffline: (userId: string) => void;
794
920
  setOnlineUsers: (userIds: string[]) => void;
921
+ setLastRead: (conversationId: string, messageId: string, readAt: string) => void;
922
+ setLastSeen: (userId: string, lastSeenAt: string) => void;
795
923
  setReplyingTo: (message: Message | null) => void;
796
924
  setEditingMessage: (message: Message | null) => void;
797
925
  toggleSidebar: () => void;
@@ -851,16 +979,17 @@ declare class AntzChatClient {
851
979
  conversationId?: string;
852
980
  }): Promise<PaginatedResponse<Message>>;
853
981
  search(params: SearchParams): Promise<PaginatedResponse<Message>>;
982
+ getLastRead(conversationId: string): Promise<{
983
+ lastReadMessageId: string | null;
984
+ lastReadAt: string | null;
985
+ }>;
854
986
  markAsRead(conversationId: string, messageId?: string): Promise<void>;
855
987
  pin(messageId: string): Promise<Message>;
856
988
  unpin(messageId: string): Promise<Message>;
857
989
  getPinned(conversationId: string): Promise<Message[]>;
858
990
  };
859
991
  readonly conversations: {
860
- list(params?: {
861
- page?: number;
862
- limit?: number;
863
- }): Promise<PaginatedResponse<Conversation>>;
992
+ list(params?: ConversationListParams): Promise<PaginatedResponse<Conversation>>;
864
993
  get(conversationId: string): Promise<Conversation>;
865
994
  createGroup(payload: CreateGroupData): Promise<Conversation>;
866
995
  createDirect(payload: CreateDirectData): Promise<Conversation>;
@@ -875,7 +1004,8 @@ declare class AntzChatClient {
875
1004
  unpin(conversationId: string): Promise<void>;
876
1005
  leave(conversationId: string): Promise<void>;
877
1006
  getMembers(conversationId: string): Promise<User[]>;
878
- searchUsers(query: string): Promise<User[]>;
1007
+ getUnreadCount(conversationId: string): Promise<ConversationUnreadCount>;
1008
+ getUnreadSummary(): Promise<UnreadSummary>;
879
1009
  };
880
1010
  readonly storage: {
881
1011
  requestPresignedUrl(payload: PresignedUrlRequest): Promise<PresignedUrlResponse>;
@@ -903,6 +1033,19 @@ declare class AntzChatClient {
903
1033
  limit?: number;
904
1034
  }): Promise<PaginatedResponse<FileResponse>>;
905
1035
  };
1036
+ readonly users: {
1037
+ list(params?: {
1038
+ query?: string;
1039
+ page?: number;
1040
+ limit?: number;
1041
+ }): Promise<PaginatedResponse<User>>;
1042
+ getById(userId: string): Promise<User>;
1043
+ getLastSeen(userId: string): Promise<{
1044
+ lastSeenAt: string | null;
1045
+ }>;
1046
+ updatePreferences(prefs: UserPreferences): Promise<User>;
1047
+ getPreferences(): Promise<UserPreferences | null>;
1048
+ };
906
1049
  readonly socket: ClientSocketHandle;
907
1050
  constructor(rawConfig: AntzChatConfig);
908
1051
  connect(): Promise<void>;
@@ -910,4 +1053,4 @@ declare class AntzChatClient {
910
1053
  uploadFiles(files: UploadableFile[], conversationId?: string): Promise<BatchUploadResult>;
911
1054
  }
912
1055
 
913
- export { AntzChatClient, type AntzChatConfig, type Attachment, type AuthResponse, type AuthTokens, type BatchUploadResult, type Conversation, type CreateDirectData, type CreateGroupData, type CursorPaginatedResponse, type EncryptedContent, type EncryptionKeyInfo, type EncryptionMode, type FileResponse, type FileSizeLimits, type FileType, type ListMessagesParams, type LoginCredentials, type Message, type MessageAckEvent, type MessageContent, type MessageDeletedEvent, type MessageDeletedForMeEvent, type MessageDeliveredEvent, type MessageReaction, type MessageReplyReference, type MessageUpdatedEvent, type MessagesDeliveredEvent, type MobileDeviceToken, type NewMessageEvent, type OptimisticAttachment, type PaginatedResponse, type Participant, type PersistStorage, type PlatformUploadFn, type PresignedUrlRequest, type PresignedUrlResponse, type ReactionUpdatedEvent, type ReadReceiptEvent, type RegisterData, type RegisterDeviceTokenPayload, type ResolvedConfig, type ResolvedFileSizeLimits, type SearchParams, type SendData, type SendMessageAttachment, type SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TypingIndicatorEvent, type UpdateConversationData, type UploadConfig, type UploadProgress, type UploadableFile, type User, type UserStatusEvent, type WebPushDeviceToken, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveConfig, setApiClientInstance, socketEmit, storageApi, tryGetSocket, uploadBatch, useChatStore };
1056
+ export { AntzChatClient, type AntzChatConfig, type Attachment, type AuthResponse, type AuthTokens, type BatchUploadResult, type Conversation, type ConversationListParams, type ConversationUnreadCount, type CreateDirectData, type CreateGroupData, type CursorPaginatedResponse, type EncryptedContent, type EncryptionKeyInfo, type EncryptionMode, type FileResponse, type FileSizeLimits, type FileType, type LastReadEntry, type ListMessagesParams, type LoginCredentials, type Message, type MessageAckEvent, type MessageContent, type MessageDeletedEvent, type MessageDeletedForMeEvent, type MessageDeliveredEvent, type MessageReaction, type MessageReplyReference, type MessageUpdatedEvent, type MessagesDeliveredEvent, type MobileDeviceToken, type NewMessageEvent, type OptimisticAttachment, type PaginatedResponse, type Participant, type PersistStorage, type PlatformUploadFn, type PresignedUrlRequest, type PresignedUrlResponse, type QuietHours, type ReactionUpdatedEvent, type ReadReceiptEvent, type RegisterData, type RegisterDeviceTokenPayload, type ResolvedConfig, type ResolvedFileSizeLimits, type SearchParams, type SendData, type SendMessageAttachment, type SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TypingIndicatorEvent, type UnreadSummary, type UpdateConversationData, type UploadConfig, type UploadProgress, type UploadableFile, type User, type UserPreferences, type UserStatusEvent, type WebPushDeviceToken, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveConfig, setApiClientInstance, socketEmit, storageApi, tryGetSocket, uploadBatch, useChatStore, usersApi };