File size: 4,367 Bytes
f0743f4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | import { LocalStorageKeys } from 'librechat-data-provider';
/** Suffix for timestamp entries */
const TIMESTAMP_SUFFIX = '_TIMESTAMP';
/** Duration in milliseconds (2 days) */
const CLEANUP_THRESHOLD = 2 * 24 * 60 * 60 * 1000;
/**
* Storage keys that should be cleaned up based on timestamps
* These are conversation-specific keys that can accumulate over time
*/
const TIMESTAMPED_KEYS = [
LocalStorageKeys.LAST_MCP_,
LocalStorageKeys.LAST_CODE_TOGGLE_,
LocalStorageKeys.LAST_WEB_SEARCH_TOGGLE_,
LocalStorageKeys.LAST_FILE_SEARCH_TOGGLE_,
LocalStorageKeys.LAST_ARTIFACTS_TOGGLE_,
LocalStorageKeys.PIN_MCP_,
];
/**
* Set only a timestamp for a key (when the value is handled elsewhere)
*/
export function setTimestamp(key: string): void {
localStorage.setItem(`${key}${TIMESTAMP_SUFFIX}`, Date.now().toString());
}
/**
* Set a value in localStorage with an associated timestamp
*/
export function setTimestampedValue(key: string, value: any): void {
localStorage.setItem(key, typeof value === 'string' ? value : JSON.stringify(value));
localStorage.setItem(`${key}${TIMESTAMP_SUFFIX}`, Date.now().toString());
}
/**
* Get a value from localStorage, checking if it has a valid timestamp
* Returns null if the value is too old or has no timestamp
*/
export function getTimestampedValue(key: string): string | null {
const timestampKey = `${key}${TIMESTAMP_SUFFIX}`;
const timestamp = localStorage.getItem(timestampKey);
if (!timestamp) {
// No timestamp exists, return the value but it will be cleaned up on next startup
return localStorage.getItem(key);
}
const age = Date.now() - parseInt(timestamp, 10);
if (age > CLEANUP_THRESHOLD) {
// Value is too old, clean it up
localStorage.removeItem(key);
localStorage.removeItem(timestampKey);
return null;
}
return localStorage.getItem(key);
}
/**
* Remove a value and its timestamp from localStorage
*/
export function removeTimestampedValue(key: string): void {
localStorage.removeItem(key);
localStorage.removeItem(`${key}${TIMESTAMP_SUFFIX}`);
}
/**
* Clean up old localStorage entries based on timestamps
* This should be called on app startup
*/
export function cleanupTimestampedStorage(): void {
try {
const keysToRemove: string[] = [];
const now = Date.now();
// Iterate through all localStorage keys
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (!key) continue;
if (key === LocalStorageKeys.PIN_MCP_) {
continue;
}
// Check if this key should be timestamped
const isTimestampedKey = TIMESTAMPED_KEYS.some(
(prefix) => key.startsWith(prefix) && !key.includes('pinned'),
);
if (isTimestampedKey && !key.endsWith(TIMESTAMP_SUFFIX)) {
const timestampKey = `${key}${TIMESTAMP_SUFFIX}`;
const timestamp = localStorage.getItem(timestampKey);
if (!timestamp) {
// No timestamp exists for a key that should have one - mark for cleanup
keysToRemove.push(key);
continue;
}
const age = now - parseInt(timestamp, 10);
if (age > CLEANUP_THRESHOLD) {
// Entry is too old - mark for cleanup
keysToRemove.push(key);
keysToRemove.push(timestampKey);
}
}
}
keysToRemove.forEach((key) => localStorage.removeItem(key));
if (keysToRemove.length > 0) {
console.log(`Cleaned up ${keysToRemove.length} old localStorage entries`);
}
} catch (error) {
console.error('Error during cleanup of timestamped storage:', error);
}
}
/**
* Migration function to add timestamps to existing entries
* This ensures existing entries don't get immediately cleaned up
*/
export function migrateExistingEntries(): void {
const now = Date.now().toString();
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (!key) continue;
const isTimestampedKey = TIMESTAMPED_KEYS.some((prefix) => key.startsWith(prefix));
if (isTimestampedKey && !key.endsWith(TIMESTAMP_SUFFIX)) {
const timestampKey = `${key}${TIMESTAMP_SUFFIX}`;
const hasTimestamp = localStorage.getItem(timestampKey);
if (!hasTimestamp) {
// Add timestamp to existing entry
localStorage.setItem(timestampKey, now);
}
}
}
}
|