diff --git a/src/stores/chat.ts b/src/stores/chat.ts index 18e3296..2bb5507 100644 --- a/src/stores/chat.ts +++ b/src/stores/chat.ts @@ -109,15 +109,26 @@ function buildChatEventDedupeKey(eventState: string, event: Record): string | null { + if (eventState !== 'final') return null; + const msg = (event.message && typeof event.message === 'object') + ? event.message as Record + : null; + if (msg?.id != null) return `final-msgid|${String(msg.id)}`; + return null; +} + function isDuplicateChatEvent(eventState: string, event: Record): boolean { const key = buildChatEventDedupeKey(eventState, event); - if (!key) return false; + const msgKey = getFinalMessageIdDedupeKey(eventState, event); + if (!key && !msgKey) return false; const now = Date.now(); pruneChatEventDedupe(now); - if (_chatEventDedupe.has(key)) { + if ((key && _chatEventDedupe.has(key)) || (msgKey && _chatEventDedupe.has(msgKey))) { return true; } - _chatEventDedupe.set(key, now); + if (key) _chatEventDedupe.set(key, now); + if (msgKey) _chatEventDedupe.set(msgKey, now); return false; } diff --git a/src/stores/gateway.ts b/src/stores/gateway.ts index aa8ab3e..5784375 100644 --- a/src/stores/gateway.ts +++ b/src/stores/gateway.ts @@ -67,15 +67,28 @@ function buildGatewayEventDedupeKey(event: Record): string | nu return null; } +function getMessageIdDedupeKey(event: Record): string | null { + const state = event.state != null ? String(event.state) : ''; + if (state !== 'final') return null; + const message = event.message; + if (message && typeof message === 'object') { + const msgId = (message as Record).id; + if (msgId != null) return `final-msgid|${String(msgId)}`; + } + return null; +} + function shouldProcessGatewayEvent(event: Record): boolean { const key = buildGatewayEventDedupeKey(event); - if (!key) return true; + const msgKey = getMessageIdDedupeKey(event); + if (!key && !msgKey) return true; const now = Date.now(); pruneGatewayEventDedupe(now); - if (gatewayEventDedupe.has(key)) { + if ((key && gatewayEventDedupe.has(key)) || (msgKey && gatewayEventDedupe.has(msgKey))) { return false; } - gatewayEventDedupe.set(key, now); + if (key) gatewayEventDedupe.set(key, now); + if (msgKey) gatewayEventDedupe.set(msgKey, now); return true; }