mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
* Process patches that are longer. * Fixed type declaration * Changed resync behavior from recusive to iterative * refactor: cleaner handling of hasMorePatches Co-authored-by: Adhiraj Singh <adhirajsingh1001@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState, ChatModification, Contact } from "../Types";
|
import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, AppStateChunk, LTHashState, ChatModification, Contact } from "../Types";
|
||||||
import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET, reduceBinaryNodeToDictionary } from "../WABinary";
|
import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET, reduceBinaryNodeToDictionary } from "../WABinary";
|
||||||
import { proto } from '../../WAProto'
|
import { proto } from '../../WAProto'
|
||||||
import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils";
|
import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils";
|
||||||
@@ -180,12 +180,17 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
const resyncAppStateInternal = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => {
|
const resyncAppStateInternal = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => {
|
||||||
if(fromScratch) returnSnapshot = true
|
if(fromScratch) returnSnapshot = true
|
||||||
|
|
||||||
const totalMutations: ChatMutation[] = []
|
const appStateChunk : AppStateChunk = {totalMutations: [], collectionsToHandle: []}
|
||||||
|
|
||||||
await authState.keys.transaction(
|
await authState.keys.transaction(
|
||||||
async() => {
|
async() => {
|
||||||
|
const collectionsToHandle = new Set<string>(collections)
|
||||||
|
// keep executing till all collections are done
|
||||||
|
// sometimes a single patch request will not return all the patches (God knows why)
|
||||||
|
// so we fetch till they're all done (this is determined by the "has_more_patches" flag)
|
||||||
|
while(collectionsToHandle.size) {
|
||||||
const states = { } as { [T in WAPatchName]: LTHashState }
|
const states = { } as { [T in WAPatchName]: LTHashState }
|
||||||
for(const name of collections) {
|
for(const name of collectionsToHandle) {
|
||||||
let state: LTHashState
|
let state: LTHashState
|
||||||
if(!fromScratch) {
|
if(!fromScratch) {
|
||||||
const result = await authState.keys.get('app-state-sync-version', [name])
|
const result = await authState.keys.get('app-state-sync-version', [name])
|
||||||
@@ -225,7 +230,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
const decoded = await extractSyncdPatches(result) // extract from binary node
|
const decoded = await extractSyncdPatches(result) // extract from binary node
|
||||||
for(const key in decoded) {
|
for(const key in decoded) {
|
||||||
const name = key as WAPatchName
|
const name = key as WAPatchName
|
||||||
const { patches, snapshot } = decoded[name]
|
const { patches, hasMorePatches, snapshot } = decoded[name]
|
||||||
if(snapshot) {
|
if(snapshot) {
|
||||||
const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey)
|
const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey)
|
||||||
states[name] = newState
|
states[name] = newState
|
||||||
@@ -243,25 +248,33 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
logger.trace({ newMutations, name }, 'recv new mutations')
|
logger.trace({ newMutations, name }, 'recv new mutations')
|
||||||
}
|
}
|
||||||
|
|
||||||
totalMutations.push(...newMutations)
|
appStateChunk.totalMutations.push(...newMutations)
|
||||||
|
}
|
||||||
|
if(hasMorePatches) {
|
||||||
|
logger.info(`${name} has more patches...`)
|
||||||
|
} else { // collection is done with sync
|
||||||
|
collectionsToHandle.delete(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
processSyncActions(totalMutations)
|
processSyncActions(appStateChunk.totalMutations)
|
||||||
|
|
||||||
return totalMutations
|
return appStateChunk
|
||||||
}
|
}
|
||||||
|
|
||||||
const resyncAppState = async(collections: WAPatchName[], returnSnapshot: boolean = false) => {
|
const resyncAppState = async(collections: WAPatchName[], returnSnapshot: boolean = false) => {
|
||||||
let result: ChatMutation[]
|
let result : AppStateChunk
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result = await resyncAppStateInternal(collections, false, returnSnapshot)
|
result = await resyncAppStateInternal(collections, false, returnSnapshot)
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
logger.info({ collections, error: error.stack }, 'failed to sync state from version, trying from scratch')
|
logger.info({ collections, error: error.stack }, 'failed to sync state from version, trying from scratch')
|
||||||
result = await resyncAppStateInternal(collections, true, true)
|
result = await resyncAppStateInternal(collections, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ export interface PresenceData {
|
|||||||
|
|
||||||
export type ChatMutation = { syncAction: proto.ISyncActionData, index: string[], indexMac: Uint8Array, valueMac: Uint8Array, operation: number }
|
export type ChatMutation = { syncAction: proto.ISyncActionData, index: string[], indexMac: Uint8Array, valueMac: Uint8Array, operation: number }
|
||||||
|
|
||||||
|
export type AppStateChunk = { totalMutations : ChatMutation[], collectionsToHandle: WAPatchName[] }
|
||||||
|
|
||||||
export type WAPatchCreate = {
|
export type WAPatchCreate = {
|
||||||
syncAction: proto.ISyncActionValue
|
syncAction: proto.ISyncActionValue
|
||||||
index: string[]
|
index: string[]
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ export const extractSyncdPatches = async(result: BinaryNode) => {
|
|||||||
const syncNode = getBinaryNodeChild(result, 'sync')
|
const syncNode = getBinaryNodeChild(result, 'sync')
|
||||||
const collectionNodes = getBinaryNodeChildren(syncNode, 'collection')
|
const collectionNodes = getBinaryNodeChildren(syncNode, 'collection')
|
||||||
|
|
||||||
const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], snapshot?: proto.ISyncdSnapshot } }
|
const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], hasMorePatches: boolean, snapshot?: proto.ISyncdSnapshot } }
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
collectionNodes.map(
|
collectionNodes.map(
|
||||||
async collectionNode => {
|
async collectionNode => {
|
||||||
@@ -284,6 +284,8 @@ export const extractSyncdPatches = async(result: BinaryNode) => {
|
|||||||
const syncds: proto.ISyncdPatch[] = []
|
const syncds: proto.ISyncdPatch[] = []
|
||||||
const name = collectionNode.attrs.name as WAPatchName
|
const name = collectionNode.attrs.name as WAPatchName
|
||||||
|
|
||||||
|
const hasMorePatches = collectionNode.attrs.has_more_patches == 'true'
|
||||||
|
|
||||||
let snapshot: proto.ISyncdSnapshot | undefined = undefined
|
let snapshot: proto.ISyncdSnapshot | undefined = undefined
|
||||||
if(snapshotNode && !!snapshotNode.content) {
|
if(snapshotNode && !!snapshotNode.content) {
|
||||||
if(!Buffer.isBuffer(snapshotNode)) {
|
if(!Buffer.isBuffer(snapshotNode)) {
|
||||||
@@ -309,7 +311,7 @@ export const extractSyncdPatches = async(result: BinaryNode) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final[name] = { patches: syncds, snapshot }
|
final[name] = { patches: syncds, hasMorePatches, snapshot }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user