refactor!: cleaner message history sync

This is a breaking change,
1. three events (chats.set, contacts.set, messages.set) are now just one `messaging-history.set` event
2. no need to debounce for app state sync
3. added a new "conditional" chat update to allow for correct app state sync despite not having the chat available on hand
This commit is contained in:
Adhiraj Singh
2022-09-29 16:32:57 +05:30
parent e08dd10198
commit d0330d1863
16 changed files with 600 additions and 309 deletions

View File

@@ -1,5 +1,6 @@
import type { proto } from '../../WAProto'
import type { AccountSettings } from './Auth'
import type { BufferedEventData } from './Events'
import type { MinimalMessage } from './Message'
/** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */
@@ -33,7 +34,23 @@ export type WAPatchCreate = {
operation: proto.SyncdMutation.SyncdOperation
}
export type Chat = proto.IConversation
export type Chat = proto.IConversation & {
/** unix timestamp of when the last message was received in the chat */
lastMessageRecvTimestamp?: number
}
export type ChatUpdate = Partial<Chat & {
/**
* if specified in the update,
* the EV buffer will check if the condition gets fulfilled before applying the update
* Right now, used to determine when to release an app state sync event
*
* @returns true, if the update should be applied;
* false if it can be discarded;
* undefined if the condition is not yet fulfilled
* */
conditional: (bufferedData: BufferedEventData) => boolean | undefined
}>
/**
* the last messages in a chat, sorted reverse-chronologically. That is, the latest message should be first in the chat
@@ -77,6 +94,5 @@ export type InitialReceivedChatsState = {
}
export type InitialAppStateSyncOptions = {
recvChats: InitialReceivedChatsState
accountSettings: AccountSettings
}

View File

@@ -2,7 +2,7 @@ import type { Boom } from '@hapi/boom'
import { proto } from '../../WAProto'
import { AuthenticationCreds } from './Auth'
import { WACallEvent } from './Call'
import { Chat, PresenceData } from './Chat'
import { Chat, ChatUpdate, PresenceData } from './Chat'
import { Contact } from './Contact'
import { GroupMetadata, ParticipantAction } from './GroupMetadata'
import { MessageUpsertType, MessageUserReceiptUpdate, WAMessage, WAMessageKey, WAMessageUpdate } from './Message'
@@ -13,16 +13,17 @@ export type BaileysEventMap = {
'connection.update': Partial<ConnectionState>
/** credentials updated -- some metadata, keys or something */
'creds.update': Partial<AuthenticationCreds>
/** set chats (history sync), chats are reverse chronologically sorted */
'chats.set': { chats: Chat[], isLatest: boolean }
/** set messages (history sync), messages are reverse chronologically sorted */
'messages.set': { messages: WAMessage[], isLatest: boolean }
/** set contacts (history sync) */
'contacts.set': { contacts: Contact[], isLatest: boolean }
/** set chats (history sync), everything is reverse chronologically sorted */
'messaging-history.set': {
chats: Chat[]
contacts: Contact[]
messages: WAMessage[]
isLatest: boolean
}
/** upsert chats */
'chats.upsert': Chat[]
/** update the given chats */
'chats.update': Partial<Chat>[]
'chats.update': ChatUpdate[]
/** delete chats with given ID */
'chats.delete': string[]
/** presence of contact in a chat updated */
@@ -56,8 +57,15 @@ export type BaileysEventMap = {
}
export type BufferedEventData = {
historySets: {
chats: { [jid: string]: Chat }
contacts: { [jid: string]: Contact }
messages: { [uqId: string]: WAMessage }
empty: boolean
isLatest: boolean
}
chatUpserts: { [jid: string]: Chat }
chatUpdates: { [jid: string]: Partial<Chat> }
chatUpdates: { [jid: string]: ChatUpdate }
chatDeletes: Set<string>
contactUpserts: { [jid: string]: Contact }
contactUpdates: { [jid: string]: Partial<Contact> }

View File

@@ -46,8 +46,8 @@ export type SocketConfig = {
qrTimeout?: number;
/** provide an auth state object to maintain the auth state */
auth: AuthenticationState
/** By default true, should history messages be downloaded and processed */
downloadHistory: boolean
/** manage history processing with this control; by default will sync up everything */
shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => boolean
/** transaction capability options for SignalKeyStore */
transactionOpts: TransactionCapabilityOptions
/** provide a cache to store a user's device list */