UNPKG

@emmahyde/thinking-patterns

Version:

MCP server combining systematic thinking, mental models, debugging approaches, and stochastic algorithms for comprehensive cognitive pattern support

105 lines (104 loc) 3.63 kB
export class InMemorySessionManager { constructor() { this.sessions = new Map(); this.SESSION_TIMEOUT_MS = 60 * 60 * 1000; // 1 hour // Run cleanup every 15 minutes this.cleanupInterval = setInterval(() => { this.cleanupExpiredSessions(); }, 15 * 60 * 1000); } createSession(sessionId) { const now = new Date(); this.sessions.set(sessionId, { thoughtHistory: [], branches: {}, createdAt: now, lastAccessedAt: now, }); } getSession(sessionId) { const session = this.sessions.get(sessionId); if (session) { session.lastAccessedAt = new Date(); return session; } return null; } clearSession(sessionId) { this.sessions.delete(sessionId); } cleanupExpiredSessions() { const now = new Date(); const expiredSessions = []; for (const [sessionId, session] of this.sessions.entries()) { const timeSinceLastAccess = now.getTime() - session.lastAccessedAt.getTime(); if (timeSinceLastAccess > this.SESSION_TIMEOUT_MS) { expiredSessions.push(sessionId); } } for (const sessionId of expiredSessions) { this.sessions.delete(sessionId); // Log cleanup to console (suppress during tests) if (process.env.NODE_ENV !== 'test' && process.env.JEST_WORKER_ID === undefined) { console.log(`Cleaned up expired session: ${sessionId}`); } } if (expiredSessions.length > 0) { // Log cleanup summary to console (suppress during tests) if (process.env.NODE_ENV !== 'test' && process.env.JEST_WORKER_ID === undefined) { console.log(`Cleaned up ${expiredSessions.length} expired sessions`); } } } addThought(sessionId, thought) { let session = this.getSession(sessionId); if (!session) { this.createSession(sessionId); session = this.getSession(sessionId); } session.thoughtHistory.push(thought); } addBranch(sessionId, branchId, thought) { let session = this.getSession(sessionId); if (!session) { this.createSession(sessionId); session = this.getSession(sessionId); } if (!session.branches[branchId]) { session.branches[branchId] = []; } session.branches[branchId].push(thought); } getThoughtHistory(sessionId) { const session = this.getSession(sessionId); return session ? [...session.thoughtHistory] : []; } getBranches(sessionId) { const session = this.getSession(sessionId); return session ? session.branches : {}; } destroy() { if (this.cleanupInterval) { clearInterval(this.cleanupInterval); } this.sessions.clear(); } // Utility methods for monitoring getSessionCount() { return this.sessions.size; } getSessionInfo() { const sessionInfo = []; for (const [sessionId, session] of this.sessions.entries()) { sessionInfo.push({ sessionId, thoughtCount: session.thoughtHistory.length, branchCount: Object.keys(session.branches).length, lastAccessed: session.lastAccessedAt, }); } return sessionInfo; } } // Export a singleton instance export const sessionManager = new InMemorySessionManager();