general: tree-shaking pre-MD and old comet versions (#5675)

Co-authored-by: BenyFilho <168232825+BenyFilho@users.noreply.github.com>
Co-authored-by: tuyuribr <45042245+tuyuribr@users.noreply.github.com>
This commit is contained in:
Rajeh Taher 2026-02-11 01:24:54 +02:00 • committed by GitHub
commit 9b1eb76b2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 70 additions and 469 deletions

View file

@ -2,15 +2,12 @@
const EventEmitter = require('events');
const puppeteer = require('puppeteer');
const moduleRaid = require('@pedroslopez/moduleraid/moduleraid');
const Util = require('./util/Util');
const InterfaceController = require('./util/InterfaceController');
const { WhatsWebURL, DefaultOptions, Events, WAState, MessageTypes } = require('./util/Constants');
const { ExposeAuthStore } = require('./util/Injected/AuthStore/AuthStore');
const { ExposeStore } = require('./util/Injected/Store');
const { ExposeLegacyAuthStore } = require('./util/Injected/AuthStore/LegacyAuthStore');
const { ExposeLegacyStore } = require('./util/Injected/LegacyStore');
const { LoadUtils } = require('./util/Injected/Utils');
const ChatFactory = require('./factories/ChatFactory');
const ContactFactory = require('./factories/ContactFactory');
@ -23,15 +20,13 @@ const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
* Starting point for interacting with the WhatsApp Web API
* @extends {EventEmitter}
* @param {object} options - Client options
* @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used.
* @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. Otherwise, NoAuth will be used.
* @param {string} options.webVersion - The version of WhatsApp Web to use. Use options.webVersionCache to configure how the version is retrieved.
* @param {object} options.webVersionCache - Determines how to retrieve the WhatsApp Web version. Defaults to a local cache (LocalWebCache) that falls back to latest if the requested version is not found.
* @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer
* @param {function} options.evalOnNewDoc - function to eval on new doc
* @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/
* @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up
* @param {string} options.restartOnAuthFail - @deprecated This option should be set directly on the LegacySessionAuth.
* @param {object} options.session - @deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.
* @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser
* @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session
* @param {string} options.userAgent - User agent to use in puppeteer
@ -113,13 +108,8 @@ class Client extends EventEmitter {
await this.setDeviceName(this.options.deviceName, this.options.browserName);
const pairWithPhoneNumber = this.options.pairWithPhoneNumber;
const version = await this.getWWebVersion();
const isCometOrAbove = parseInt(version.split('.')?.[1]) >= 3000;
if (isCometOrAbove) {
await this.pupPage.evaluate(ExposeAuthStore);
} else {
await this.pupPage.evaluate(ExposeLegacyAuthStore, moduleRaid.toString());
}
await this.pupPage.evaluate(ExposeAuthStore);
const needAuthentication = await this.pupPage.evaluate(async () => {
let state = window.AuthStore.AppState.state;
@ -231,14 +221,8 @@ class Client extends EventEmitter {
await webCache.persist(this.currentIndexHtml, version);
}
if (isCometOrAbove) {
await this.pupPage.evaluate(ExposeStore);
} else {
// make sure all modules are ready before injection
// 2 second delay after authentication makes sense and does not need to be made dyanmic or removed
await new Promise(r => setTimeout(r, 2000));
await this.pupPage.evaluate(ExposeLegacyStore);
}
await this.pupPage.evaluate(ExposeStore);
let start = Date.now();
let res = false;
while(start > (Date.now() - 30000)){
@ -354,17 +338,14 @@ class Client extends EventEmitter {
}
// ocVersion (isOfficialClient patch)
// remove after 2.3000.x hard release
await page.evaluateOnNewDocument(() => {
const originalError = Error;
window.originalError = originalError;
window.originalError = Error;
//eslint-disable-next-line no-global-assign
Error = function (message) {
const error = new originalError(message);
const originalStack = error.stack;
if (error.stack.includes('moduleRaid')) error.stack = originalStack + '\n at https://web.whatsapp.com/vendors~lazy_loaded_low_priority_components.05e98054dbd60f980427.js:2:44';
Error = ((message) => {
const error = new window.originalError(message);
error.stack = error.stack + '\n at https://web.whatsapp.com/vendors~lazy_loaded_low_priority_components.05e98054dbd60f980427.js:2:44';
return error;
};
}).bind(Error);
});
await page.goto(WhatsWebURL, {
@ -778,70 +759,54 @@ class Client extends EventEmitter {
});
window.Store.Chat.on('change:unreadCount', (chat) => {window.onChatUnreadCountEvent(chat);});
if (window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.1014111620')) {
const module = window.Store.AddonReactionTable;
const ogMethod = module.bulkUpsert;
module.bulkUpsert = ((...args) => {
window.onReaction(args[0].map(reaction => {
const msgKey = reaction.id;
const parentMsgKey = reaction.reactionParentKey;
const timestamp = reaction.reactionTimestamp / 1000;
const sender = reaction.author ?? reaction.from;
const senderUserJid = sender._serialized;
const module = window.Store.AddonReactionTable;
const ogMethod = module.bulkUpsert;
module.bulkUpsert = ((...args) => {
window.onReaction(args[0].map(reaction => {
const msgKey = reaction.id;
const parentMsgKey = reaction.reactionParentKey;
const timestamp = reaction.reactionTimestamp / 1000;
const sender = reaction.author ?? reaction.from;
const senderUserJid = sender._serialized;
return {...reaction, msgKey, parentMsgKey, senderUserJid, timestamp };
}));
return {...reaction, msgKey, parentMsgKey, senderUserJid, timestamp };
}));
return ogMethod(...args);
}).bind(module);
return ogMethod(...args);
}).bind(module);
const pollVoteModule = window.Store.AddonPollVoteTable;
const ogPollVoteMethod = pollVoteModule.bulkUpsert;
const pollVoteModule = window.Store.AddonPollVoteTable;
const ogPollVoteMethod = pollVoteModule.bulkUpsert;
pollVoteModule.bulkUpsert = (async (...args) => {
const votes = await Promise.all(args[0].map(async vote => {
const msgKey = vote.id;
const parentMsgKey = vote.pollUpdateParentKey;
const timestamp = vote.t / 1000;
const sender = vote.author ?? vote.from;
const senderUserJid = sender._serialized;
pollVoteModule.bulkUpsert = (async (...args) => {
const votes = await Promise.all(args[0].map(async vote => {
const msgKey = vote.id;
const parentMsgKey = vote.pollUpdateParentKey;
const timestamp = vote.t / 1000;
const sender = vote.author ?? vote.from;
const senderUserJid = sender._serialized;
let parentMessage = window.Store.Msg.get(parentMsgKey._serialized);
if (!parentMessage) {
const fetched = await window.Store.Msg.getMessagesById([parentMsgKey._serialized]);
parentMessage = fetched?.messages?.[0] || null;
}
let parentMessage = window.Store.Msg.get(parentMsgKey._serialized);
if (!parentMessage) {
const fetched = await window.Store.Msg.getMessagesById([parentMsgKey._serialized]);
parentMessage = fetched?.messages?.[0] || null;
}
return {
...vote,
msgKey,
sender,
parentMsgKey,
senderUserJid,
timestamp,
parentMessage
};
}));
return {
...vote,
msgKey,
sender,
parentMsgKey,
senderUserJid,
timestamp,
parentMessage
};
}));
window.onPollVoteEvent(votes);
window.onPollVoteEvent(votes);
return ogPollVoteMethod.apply(pollVoteModule, args);
}).bind(pollVoteModule);
} else {
const module = window.Store.createOrUpdateReactionsModule;
const ogMethod = module.createOrUpdateReactions;
module.createOrUpdateReactions = ((...args) => {
window.onReaction(args[0].map(reaction => {
const msgKey = window.Store.MsgKey.fromString(reaction.msgKey);
const parentMsgKey = window.Store.MsgKey.fromString(reaction.parentMsgKey);
const timestamp = reaction.timestamp / 1000;
return {...reaction, msgKey, parentMsgKey, timestamp };
}));
return ogMethod(...args);
}).bind(module);
}
return ogPollVoteMethod.apply(pollVoteModule, args);
}).bind(pollVoteModule);
});
}
@ -1564,9 +1529,7 @@ class Client extends EventEmitter {
const profilePic = await this.pupPage.evaluate(async contactId => {
try {
const chatWid = window.Store.WidFactory.createWid(contactId);
return window.compareWwebVersions(window.Debug.VERSION, '<', '2.3000.0')
? await window.Store.ProfilePic.profilePicFind(chatWid)
: await window.Store.ProfilePic.requestProfilePicFromServer(chatWid);
return await window.Store.ProfilePic.requestProfilePicFromServer(chatWid);
} catch (err) {
if(err.name === 'ServerStatusCodeError') return undefined;
throw err;