support bot, bots: paginate chat scan (#6935)

* bots: document APIGetChats command and CRApiChats response

* bots: regenerate API docs and TypeScript types

* simplex-chat-nodejs: add apiGetChats

* support bot: avoid OOM on large databases

apiListGroups / apiListContacts return every record in one response and
overflow V8's string allocation on large DBs. Replace list-then-find-by-id
patterns with apiGetChat(type, id, 0) lookups, and the one genuine scan
(refreshAllCards) with paginated apiGetChats, count=1000.

* support bot: update test assertions to match current message text

* bots: simplify PaginationByTime, expose only PTLast

* simplex-chat-nodejs: bump types and nodejs versions
This commit is contained in:
sh
2026-05-06 07:54:36 +00:00
committed by GitHub
parent db783d85d7
commit fefdea8ed0
22 changed files with 673 additions and 62 deletions
+1 -1
View File
@@ -144,6 +144,7 @@ chatCommandsDocsData =
"Commands to list and delete conversations.",
[ ("APIListContacts", [], "Get contacts.", ["CRContactsList", "CRChatCmdError"], [], Nothing, "/_contacts " <> Param "userId"),
("APIListGroups", [], "Get groups.", ["CRGroupsList", "CRChatCmdError"], [], Nothing, "/_groups " <> Param "userId" <> Optional "" (" @" <> Param "$0") "contactId_" <> Optional "" (" " <> Param "$0") "search"),
("APIGetChats", [], "Get chat previews. Supports time-based pagination — use this instead of APIListContacts / APIListGroups when scanning at scale (those load every record into memory and fail on large databases).", ["CRApiChats", "CRChatCmdError"], [], Nothing, "/_get chats " <> Param "userId" <> OnOffParam "pcc" "pendingConnections" (Just False) <> " " <> Param "pagination" <> " " <> Json "query"),
("APIDeleteChat", [], "Delete chat.", ["CRContactDeleted", "CRContactConnectionDeleted", "CRGroupDeletedUser", "CRChatCmdError"], [], Just UNBackground, "/_delete " <> Param "chatRef" <> " " <> Param "chatDeleteMode"),
("APISetGroupCustomData", [], "Set group custom data.", ["CRCmdOk", "CRChatCmdError"], [], Nothing, "/_set custom #" <> Param "groupId" <> Optional "" (" " <> Json "$0") "customData"),
("APISetContactCustomData", [], "Set contact custom data.", ["CRCmdOk", "CRChatCmdError"], [], Nothing, "/_set custom @" <> Param "contactId" <> Optional "" (" " <> Json "$0") "customData"),
@@ -357,7 +358,6 @@ undocumentedCommands =
"APIGetChatItemInfo",
"APIGetChatItems",
"APIGetChatItemTTL",
"APIGetChats",
"APIGetChatTags",
"APIGetConnNtfMessages",
"APIGetContactCode",
+2 -3
View File
@@ -95,9 +95,9 @@ chatResponsesDocsData =
("CRUserDeletedMembers", "Members deleted"),
("CRUserProfileUpdated", "User profile updated"),
("CRUserProfileNoChange", "User profile was not changed"),
("CRUsersList", "Users")
("CRUsersList", "Users"),
("CRApiChats", "Chat previews (paginated). Use this instead of CRContactsList / CRGroupsList when scanning at scale.")
-- ("CRApiChat", "Chat and messages"),
-- ("CRApiChats", "Chats with the most recent messages"),
-- ("CRChatCleared", ""),
-- ("CRChatItemInfo", "Message information"),
-- ("CRChatItems", "The most recent messages"),
@@ -120,7 +120,6 @@ undocumentedResponses =
"CRAgentWorkersDetails",
"CRAgentWorkersSummary",
"CRApiChat",
"CRApiChats",
"CRAppSettings",
"CRArchiveExported",
"CRArchiveImported",
+8 -5
View File
@@ -374,11 +374,11 @@ chatTypesDocsData =
(sti @UserPwdHash, STRecord, "", [], "", ""),
(sti @XFTPErrorType, STUnion, "", [], "", ""),
(sti @XFTPRcvFile, STRecord, "", [], "", ""),
(sti @XFTPSndFile, STRecord, "", [], "", "")
(sti @XFTPSndFile, STRecord, "", [], "", ""),
-- (sti @DatabaseError, STUnion, "DB", [], "", ""),
-- (sti @ChatItemInfo, STRecord, "", [], "", ""),
-- (sti @ChatItemVersion, STRecord, "", [], "", ""),
-- (sti @ChatListQuery, STUnion, "CLQ", [], "", ""),
(sti @ChatListQuery, STUnion, "CLQ", [], "", ""),
-- (sti @ChatName, STRecord, "", [], "", ""),
-- (sti @ChatPagination, STRecord, "CP", [], "", ""),
-- (sti @ConnectionStats, STRecord, "", [], "", ""),
@@ -387,7 +387,10 @@ chatTypesDocsData =
-- (sti @MemberReaction, STRecord, "", [], "", ""),
-- (sti @MsgContentTag, (STEnum' $ dropPfxSfx "MC" '_'), "", ["MCUnknown_"], "", ""),
-- (sti @NavigationInfo, STRecord, "", [], "", ""),
-- (sti @PaginationByTime, STRecord, "", [], "", ""),
-- PTAfter / PTBefore are hidden — bots only need "tail last N chats".
-- The wire format is parsed by paginationByTimeP in
-- src/Simplex/Chat/Library/Commands.hs.
(sti @PaginationByTime, STUnion1, "PT", ["PTAfter", "PTBefore"], "count=" <> Param "count", "")
-- (sti @RcvQueueInfo, STRecord, "", [], "", ""),
-- (sti @RcvSwitchStatus, STEnum, "", [], "", ""), -- incorrect
-- (sti @SendRef, STRecord, "", [], "", ""),
@@ -589,7 +592,7 @@ deriving instance Generic XFTPSndFile
-- deriving instance Generic DatabaseError
-- deriving instance Generic ChatItemInfo
-- deriving instance Generic ChatItemVersion
-- deriving instance Generic ChatListQuery
deriving instance Generic ChatListQuery
-- deriving instance Generic ChatName
-- deriving instance Generic ChatPagination
-- deriving instance Generic ConnectionStats
@@ -599,7 +602,7 @@ deriving instance Generic XFTPSndFile
-- deriving instance Generic MemberReaction
-- deriving instance Generic MsgContentTag
-- deriving instance Generic NavigationInfo
-- deriving instance Generic PaginationByTime
deriving instance Generic PaginationByTime
-- deriving instance Generic RcvQueueInfo
-- deriving instance Generic RcvSwitchStatus
-- deriving instance Generic SendRef