@endlessblink/like-i-said-v2
Version:
Task Management & Memory for Claude - Track tasks, remember context, and maintain continuity across sessions with 27 powerful tools. Works with Claude Desktop and Claude Code.
121 lines (103 loc) • 3.58 kB
text/typescript
export class MemoryManager {
private static instance: MemoryManager;
private graphInstances = new WeakSet<any>();
static getInstance(): MemoryManager {
if (!MemoryManager.instance) {
MemoryManager.instance = new MemoryManager();
}
return MemoryManager.instance;
}
// Optimize memory data before processing
optimizeMemoryData(memories: any[], maxNodes: number = 100): any[] {
return memories
.filter(memory => memory && memory.id && (memory.title || memory.content))
.sort((a, b) => {
// Prioritize by importance or recency
const scoreA = this.calculateMemoryScore(a);
const scoreB = this.calculateMemoryScore(b);
return scoreB - scoreA;
})
.slice(0, maxNodes);
}
private calculateMemoryScore(memory: any): number {
let score = 0;
// Recency bonus
if (memory.timestamp || memory.createdAt) {
const timestamp = memory.timestamp || memory.createdAt;
const age = Date.now() - new Date(timestamp).getTime();
const daysSinceCreation = age / (1000 * 60 * 60 * 24);
score += Math.max(0, 100 - daysSinceCreation);
}
// Content richness bonus
score += (memory.content?.length || 0) * 0.01;
score += (memory.tags?.length || 0) * 10;
// Category bonus
if (memory.category) {
score += 5;
}
return score;
}
// Debounce graph updates to prevent excessive re-renders
debounceGraphUpdate(updateFunction: Function, delay: number = 300): Function {
let timeoutId: NodeJS.Timeout;
return (...args: any[]) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => updateFunction(...args), delay);
};
}
// Monitor memory usage
getMemoryUsage(): { used: number; total: number; percentage: number } | null {
if ('memory' in performance) {
const memory = (performance as any).memory;
const used = memory.usedJSHeapSize / 1048576; // MB
const total = memory.totalJSHeapSize / 1048576; // MB
const percentage = (used / total) * 100;
return {
used,
total,
percentage
};
}
return null;
}
// Clean up resources
cleanup(graphInstance?: any): void {
if (graphInstance) {
try {
if (typeof graphInstance.clear === 'function') {
graphInstance.clear();
}
this.graphInstances.delete(graphInstance);
} catch (error) {
console.warn('Error during graph cleanup:', error);
}
}
// Force garbage collection if available (development only)
if (process.env.NODE_ENV === 'development' && 'gc' in window) {
(window as any).gc();
}
}
// Track graph instance
trackGraphInstance(instance: any): void {
this.graphInstances.add(instance);
}
// Check if memory usage is high
isMemoryUsageHigh(): boolean {
const usage = this.getMemoryUsage();
if (usage) {
return usage.percentage > 80;
}
return false;
}
// Get recommended max nodes based on available memory
getRecommendedMaxNodes(): number {
const usage = this.getMemoryUsage();
if (!usage) return 100; // Default
// Adjust max nodes based on available memory
if (usage.percentage > 70) return 50;
if (usage.percentage > 50) return 75;
if (usage.percentage > 30) return 100;
return 150;
}
}
export const memoryManager = MemoryManager.getInstance();