@@ -46,8 +46,51 @@ import type { WebInboundMessage, WebListenerCloseReason } from "./types.js";
4646
4747const LOGGED_OUT_STATUS = DisconnectReason ?. loggedOut ?? 401 ;
4848const RECONNECT_IN_PROGRESS_ERROR = "no active socket - reconnection in progress" ;
49+ const GROUP_META_TTL_MS = 5 * 60 * 1000 ; // 5 minutes
50+ export const WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES = 500 ;
4951
50- export type WhatsAppGroupMetadataCache = Map < string , GroupMetadata > ;
52+ export type WhatsAppGroupMetadataCacheEntry = {
53+ subject ?: string ;
54+ participants ?: string [ ] ;
55+ expires : number ;
56+ } ;
57+ export type WhatsAppGroupMetadataCache = Map < string , WhatsAppGroupMetadataCacheEntry > ;
58+
59+ function rememberGroupMetadataCacheEntry (
60+ cache : WhatsAppGroupMetadataCache ,
61+ jid : string ,
62+ entry : WhatsAppGroupMetadataCacheEntry ,
63+ ) : void {
64+ if ( cache . has ( jid ) ) {
65+ cache . delete ( jid ) ;
66+ }
67+ cache . set ( jid , entry ) ;
68+
69+ while ( cache . size > WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES ) {
70+ const oldest = cache . keys ( ) . next ( ) ;
71+ if ( oldest . done ) {
72+ break ;
73+ }
74+ cache . delete ( oldest . value ) ;
75+ }
76+ }
77+
78+ function readGroupMetadataCacheEntry (
79+ cache : WhatsAppGroupMetadataCache ,
80+ jid : string ,
81+ ) : WhatsAppGroupMetadataCacheEntry | null {
82+ const entry = cache . get ( jid ) ;
83+ if ( ! entry ) {
84+ return null ;
85+ }
86+ if ( entry . expires <= Date . now ( ) ) {
87+ cache . delete ( jid ) ;
88+ return null ;
89+ }
90+ cache . delete ( jid ) ;
91+ cache . set ( jid , entry ) ;
92+ return entry ;
93+ }
5194
5295function logWhatsAppVerbose ( enabled : boolean | undefined , message : string ) {
5396 if ( ! enabled ) {
@@ -239,12 +282,8 @@ export async function attachWebInboxToSocket(
239282 inboundConsoleLog . error ( `Failed handling inbound web message: ${ String ( err ) } ` ) ;
240283 } ,
241284 } ) ;
242- const groupMetadataCache = options . groupMetadataCache ?? new Map < string , GroupMetadata > ( ) ;
243- const groupMetaCache = new Map <
244- string ,
245- { subject ?: string ; participants ?: string [ ] ; expires : number }
246- > ( ) ;
247- const GROUP_META_TTL_MS = 5 * 60 * 1000 ; // 5 minutes
285+ const groupMetadataCache = options . groupMetadataCache ?? new Map ( ) ;
286+ const groupMetaCache : WhatsAppGroupMetadataCache = new Map ( ) ;
248287 const lidLookup = sock . signalRepository ?. lidMapping ;
249288
250289 const resolveInboundJid = async ( jid : string | null | undefined ) : Promise < string | null > =>
@@ -330,26 +369,25 @@ export async function attachWebInboxToSocket(
330369 } ;
331370
332371 const getGroupMeta = async ( jid : string ) => {
333- const cached = groupMetaCache . get ( jid ) ;
334- if ( cached && cached . expires > Date . now ( ) ) {
372+ const cached = readGroupMetadataCacheEntry ( groupMetaCache , jid ) ;
373+ if ( cached ) {
335374 return cached ;
336375 }
337376 try {
338377 const meta = await sock . groupMetadata ( jid ) ;
339- groupMetadataCache . set ( jid , meta ) ;
340378 const entry = await summarizeGroupMeta ( meta ) ;
341- groupMetaCache . set ( jid , entry ) ;
379+ rememberGroupMetadataCacheEntry ( groupMetadataCache , jid , entry ) ;
380+ rememberGroupMetadataCacheEntry ( groupMetaCache , jid , entry ) ;
342381 return entry ;
343382 } catch ( err ) {
344- const hydrated = groupMetadataCache . get ( jid ) ;
383+ const hydrated = readGroupMetadataCacheEntry ( groupMetadataCache , jid ) ;
345384 if ( hydrated ) {
346- const entry = await summarizeGroupMeta ( hydrated ) ;
347- groupMetaCache . set ( jid , entry ) ;
385+ rememberGroupMetadataCacheEntry ( groupMetaCache , jid , hydrated ) ;
348386 logWhatsAppVerbose (
349387 options . verbose ,
350388 `Using cached group metadata for ${ jid } after fetch failure: ${ String ( err ) } ` ,
351389 ) ;
352- return entry ;
390+ return hydrated ;
353391 }
354392 logWhatsAppVerbose (
355393 options . verbose ,
@@ -756,7 +794,7 @@ export async function attachWebInboxToSocket(
756794 const groups = await sock . groupFetchAllParticipating ( ) ;
757795 for ( const [ jid , meta ] of Object . entries ( groups ?? { } ) ) {
758796 if ( meta ) {
759- groupMetadataCache . set ( jid , meta ) ;
797+ rememberGroupMetadataCacheEntry ( groupMetadataCache , jid , await summarizeGroupMeta ( meta ) ) ;
760798 }
761799 }
762800 logWhatsAppVerbose (
0 commit comments