From a427f9d2091016cc2bbc8ad9d8e6f43973ea00f9 Mon Sep 17 00:00:00 2001 From: Dan Ditomaso Date: Fri, 24 Apr 2026 22:25:51 -0400 Subject: [PATCH] chore(web): drop saveMessage path from subscriptions, delete dead DTO The SDK chat slice now persists every inbound/outbound text packet via the SqlocalMessageRepository wired in useConnections, so the legacy Zustand saveMessage path in subscriptions.ts was writing to a store no UI code reads from. - subscriptions.ts: removed saveMessage call + PacketToMessageDTO usage. Unread-count increments retained as-is (cross-cutting concern, migrates in a separate commit). - subscribeAll's messageStore parameter retained as `_messageStore` for callsite stability while the rest of the legacy store is being retired. - Deleted packages/web/src/core/dto/PacketToMessageDTO.ts (no remaining consumers; SDK has its own MessageMapper at packages/sdk/src/features/chat/infrastructure/MessageMapper.ts). Web tests (294) still green; production build clean. Out of scope, queued: - useConnections refactor (the hook is overdue for cleanup) - Strip dead methods from the Zustand messageStore (saveMessage, getMessages, setMessageState, getDraft, setDraft, clearDraft + Zustand-persist + IDB wrapper). Requires a follow-up sweep of the remaining test files that mock those methods. - Migrate unread counts to the SDK (cross-cutting between chat + nodes). --- .../web/src/core/dto/PacketToMessageDTO.ts | 53 ------------------- packages/web/src/core/subscriptions.ts | 35 +++++++----- 2 files changed, 21 insertions(+), 67 deletions(-) delete mode 100644 packages/web/src/core/dto/PacketToMessageDTO.ts diff --git a/packages/web/src/core/dto/PacketToMessageDTO.ts b/packages/web/src/core/dto/PacketToMessageDTO.ts deleted file mode 100644 index a608c451..00000000 --- a/packages/web/src/core/dto/PacketToMessageDTO.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { MessageState, MessageType } from "@core/stores"; -import type { Message } from "@core/stores/messageStore/types.ts"; -import type { Types } from "@meshtastic/sdk"; - -class PacketToMessageDTO { - channel: Types.ChannelNumber; - to: number; - from: number; - date: number; // (timestamp ms) - messageId: number; - state: MessageState; - message: string; - type: MessageType; - - constructor(data: Types.PacketMetadata, nodeNum: number) { - this.channel = data.channel; - this.to = data.to; - this.from = data.from; - this.messageId = data.id; - this.state = data.from !== nodeNum ? MessageState.Ack : MessageState.Waiting; - this.message = data.data; - this.type = data.type === "direct" ? MessageType.Direct : MessageType.Broadcast; - - let dateTimestamp = Date.now(); - if (data.rxTime instanceof Date) { - const timeValue = data.rxTime.getTime(); - - if (!Number.isNaN(timeValue)) { - dateTimestamp = timeValue; - } - } else if (data.rxTime != null) { - console.warn( - `Received rxTime in PacketToMessageDTO was not a Date object as expected (type: ${typeof data.rxTime}, value: ${data.rxTime}). Using current time as fallback.`, - ); - } - this.date = dateTimestamp; - } - - toMessage(): Message { - return { - channel: this.channel, - to: this.to, - from: this.from, - date: this.date, - messageId: this.messageId, - state: this.state, - message: this.message, - type: this.type, - }; - } -} - -export default PacketToMessageDTO; diff --git a/packages/web/src/core/subscriptions.ts b/packages/web/src/core/subscriptions.ts index c562084b..da519192 100644 --- a/packages/web/src/core/subscriptions.ts +++ b/packages/web/src/core/subscriptions.ts @@ -1,11 +1,21 @@ -import PacketToMessageDTO from "@core/dto/PacketToMessageDTO.ts"; import { useNewNodeNum } from "@core/hooks/useNewNodeNum"; -import { type Device, type MessageStore, MessageType, type NodeDB } from "@core/stores"; +import { type Device, type MessageStore, type NodeDB } from "@core/stores"; import { type MeshDevice, Protobuf } from "@meshtastic/sdk"; + +/** + * Wires up the legacy MeshDevice event stream into the web's Zustand stores. + * + * Note: the SDK chat slice already persists messages via the configured + * SqlocalMessageRepository, so this function no longer copies messages into + * the legacy messageStore. Unread-count increments stay here because that + * logic still lives on the device store; it migrates to the SDK in a + * follow-up "unread" cross-cutting commit. + */ export const subscribeAll = ( device: Device, connection: MeshDevice, - messageStore: MessageStore, + // biome-ignore lint/correctness/noUnusedFunctionParameters: kept for callsite stability while messageStore is being retired + _messageStore: MessageStore, nodeDB: NodeDB, ) => { let myNodeNum = 0; @@ -78,19 +88,16 @@ export const subscribeAll = ( }); connection.events.onMessagePacket.subscribe((messagePacket) => { - // incoming and outgoing messages are handled by this event listener - const dto = new PacketToMessageDTO(messagePacket, myNodeNum); - const message = dto.toMessage(); - messageStore.saveMessage(message); - - if (message.type === MessageType.Direct) { - if (message.to === myNodeNum) { + // Message persistence is handled by the SDK chat slice via the + // SqlocalMessageRepository wired in useConnections. This handler exists + // only to drive the legacy unread-count tracking on the device store. + const isDirect = messagePacket.type === "direct"; + if (isDirect) { + if (messagePacket.to === myNodeNum) { device.incrementUnread(messagePacket.from); } - } else if (message.type === MessageType.Broadcast) { - if (message.from !== myNodeNum) { - device.incrementUnread(message.channel); - } + } else if (messagePacket.from !== myNodeNum) { + device.incrementUnread(messagePacket.channel); } });