From f1189af67783db08dc78b966eb8f628c82aad9ee Mon Sep 17 00:00:00 2001 From: Nuwan Date: Sun, 8 Feb 2026 20:51:14 +0530 Subject: [PATCH] feat(21-01): add MAX_MESSAGES limit to sessionChatSlice.js - Add MAX_MESSAGES = 500 constant to bound chat message storage - Apply slice(-MAX_MESSAGES) in addMessageFromWebSocket reducer - Apply slice(-MAX_MESSAGES) in fetchChatHistory.fulfilled reducer - Apply slice(-MAX_MESSAGES) in uploadAttachment.fulfilled reducer Fixes CHAT-02: Prevents unbounded memory growth from chat activity --- jam-ui/src/store/features/sessionChatSlice.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/jam-ui/src/store/features/sessionChatSlice.js b/jam-ui/src/store/features/sessionChatSlice.js index 6090d7ab9..a664cf40b 100644 --- a/jam-ui/src/store/features/sessionChatSlice.js +++ b/jam-ui/src/store/features/sessionChatSlice.js @@ -2,6 +2,12 @@ import { createSlice, createAsyncThunk, createSelector } from '@reduxjs/toolkit' import { getChatMessages, sendChatMessage, uploadMusicNotation } from '../../helpers/rest'; import { saveLastReadAt, loadLastReadAt } from '../../helpers/chatStorage'; +/** + * Maximum messages retained per channel to prevent unbounded memory growth + * Oldest messages are removed when this limit is exceeded + */ +const MAX_MESSAGES = 500; + /** * Async thunk to fetch chat history for a channel * @param {Object} params - Request parameters @@ -206,6 +212,9 @@ const sessionChatSlice = createSlice({ new Date(a.createdAt) - new Date(b.createdAt) ); + // Limit messages to MAX_MESSAGES to prevent unbounded memory growth + state.messagesByChannel[channel] = state.messagesByChannel[channel].slice(-MAX_MESSAGES); + // Increment unread count if window closed OR viewing different channel if (!state.isWindowOpen || state.activeChannel !== channel) { state.unreadCounts[channel] = (state.unreadCounts[channel] || 0) + 1; @@ -370,6 +379,9 @@ const sessionChatSlice = createSlice({ new Date(a.createdAt) - new Date(b.createdAt) ); + // Limit messages to MAX_MESSAGES to prevent unbounded memory growth + state.messagesByChannel[channel] = state.messagesByChannel[channel].slice(-MAX_MESSAGES); + state.fetchStatus[channel] = 'succeeded'; state.nextCursors[channel] = next; @@ -515,6 +527,9 @@ const sessionChatSlice = createSlice({ state.messagesByChannel[channel].sort((a, b) => new Date(a.createdAt) - new Date(b.createdAt) ); + + // Limit messages to MAX_MESSAGES to prevent unbounded memory growth + state.messagesByChannel[channel] = state.messagesByChannel[channel].slice(-MAX_MESSAGES); } } })