👻 refactor: LocalStorage Cleanup and MCP State Optimization (#9528)

* 👻 refactor: MCP Select State with Jotai Atoms

* refactor: Implement timestamp management for ChatArea localStorage entries

* refactor: Integrate MCP Server Manager into BadgeRow context and components to avoid double-calling within BadgeRow

* refactor: add try/catch

* chore: remove comment
This commit is contained in:
Danny Avila 2025-09-09 17:32:10 -04:00 committed by GitHub
parent 519645c0b0
commit 751c2e1d17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 435 additions and 115 deletions

View file

@ -0,0 +1,163 @@
import { LocalStorageKeys } from 'librechat-data-provider';
import {
setTimestamp,
setTimestampedValue,
getTimestampedValue,
removeTimestampedValue,
cleanupTimestampedStorage,
migrateExistingEntries,
} from '../timestamps';
describe('timestamps', () => {
beforeEach(() => {
localStorage.clear();
jest.clearAllMocks();
});
describe('setTimestamp', () => {
it('should set only timestamp in localStorage', () => {
const key = 'test-key';
setTimestamp(key);
expect(localStorage.getItem(`${key}_TIMESTAMP`)).toBeTruthy();
expect(localStorage.getItem(key)).toBeNull();
});
});
describe('setTimestampedValue', () => {
it('should set value and timestamp in localStorage', () => {
const key = 'test-key';
const value = { data: 'test' };
setTimestampedValue(key, value);
expect(localStorage.getItem(key)).toBe(JSON.stringify(value));
expect(localStorage.getItem(`${key}_TIMESTAMP`)).toBeTruthy();
});
});
describe('getTimestampedValue', () => {
it('should return value if timestamp is valid', () => {
const key = 'test-key';
const value = { data: 'test' };
localStorage.setItem(key, JSON.stringify(value));
localStorage.setItem(`${key}_TIMESTAMP`, Date.now().toString());
const result = getTimestampedValue(key);
expect(result).toBe(JSON.stringify(value));
});
it('should return null and clean up if timestamp is too old', () => {
const key = 'test-key';
const value = { data: 'test' };
const oldTimestamp = Date.now() - 3 * 24 * 60 * 60 * 1000; // 3 days ago
localStorage.setItem(key, JSON.stringify(value));
localStorage.setItem(`${key}_TIMESTAMP`, oldTimestamp.toString());
const result = getTimestampedValue(key);
expect(result).toBeNull();
expect(localStorage.getItem(key)).toBeNull();
expect(localStorage.getItem(`${key}_TIMESTAMP`)).toBeNull();
});
it('should return value if no timestamp exists (backward compatibility)', () => {
const key = 'test-key';
const value = { data: 'test' };
localStorage.setItem(key, JSON.stringify(value));
const result = getTimestampedValue(key);
expect(result).toBe(JSON.stringify(value));
});
});
describe('removeTimestampedValue', () => {
it('should remove both value and timestamp', () => {
const key = 'test-key';
localStorage.setItem(key, 'value');
localStorage.setItem(`${key}_TIMESTAMP`, Date.now().toString());
removeTimestampedValue(key);
expect(localStorage.getItem(key)).toBeNull();
expect(localStorage.getItem(`${key}_TIMESTAMP`)).toBeNull();
});
});
describe('cleanupTimestampedStorage', () => {
it('should remove entries without timestamps', () => {
const key = `${LocalStorageKeys.LAST_MCP_}convo-123`;
localStorage.setItem(key, 'value');
cleanupTimestampedStorage();
expect(localStorage.getItem(key)).toBeNull();
});
it('should remove old entries with timestamps', () => {
const key = `${LocalStorageKeys.LAST_CODE_TOGGLE_}convo-456`;
const oldTimestamp = Date.now() - 3 * 24 * 60 * 60 * 1000; // 3 days ago
localStorage.setItem(key, 'true');
localStorage.setItem(`${key}_TIMESTAMP`, oldTimestamp.toString());
cleanupTimestampedStorage();
expect(localStorage.getItem(key)).toBeNull();
expect(localStorage.getItem(`${key}_TIMESTAMP`)).toBeNull();
});
it('should keep recent entries', () => {
const key = `${LocalStorageKeys.LAST_WEB_SEARCH_TOGGLE_}convo-789`;
const recentTimestamp = Date.now() - 1 * 60 * 60 * 1000; // 1 hour ago
localStorage.setItem(key, 'false');
localStorage.setItem(`${key}_TIMESTAMP`, recentTimestamp.toString());
cleanupTimestampedStorage();
expect(localStorage.getItem(key)).toBe('false');
expect(localStorage.getItem(`${key}_TIMESTAMP`)).toBe(recentTimestamp.toString());
});
it('should not affect non-timestamped keys', () => {
const regularKey = 'regular-key';
localStorage.setItem(regularKey, 'value');
cleanupTimestampedStorage();
expect(localStorage.getItem(regularKey)).toBe('value');
});
});
describe('migrateExistingEntries', () => {
it('should add timestamps to existing timestamped keys', () => {
const key1 = `${LocalStorageKeys.LAST_MCP_}convo-111`;
const key2 = `${LocalStorageKeys.PIN_MCP_}convo-222`;
localStorage.setItem(key1, '["mcp1", "mcp2"]');
localStorage.setItem(key2, 'true');
migrateExistingEntries();
expect(localStorage.getItem(`${key1}_TIMESTAMP`)).toBeTruthy();
expect(localStorage.getItem(`${key2}_TIMESTAMP`)).toBeTruthy();
});
it('should not overwrite existing timestamps', () => {
const key = `${LocalStorageKeys.LAST_FILE_SEARCH_TOGGLE_}convo-333`;
const existingTimestamp = '1234567890';
localStorage.setItem(key, 'true');
localStorage.setItem(`${key}_TIMESTAMP`, existingTimestamp);
migrateExistingEntries();
expect(localStorage.getItem(`${key}_TIMESTAMP`)).toBe(existingTimestamp);
});
});
});