const { v4: uuid } = require('uuid'); class SessionStore { constructor() { this.sessions = new Map(); this.profileIndex = new Map(); } create(payload, customId, ttlMs) { const id = customId || uuid(); const profileId = payload?.profile?.id ? String(payload.profile.id) : null; if (profileId && this.profileIndex.has(profileId)) { const previousId = this.profileIndex.get(profileId); if (previousId && previousId !== id) { this.delete(previousId); } } const session = { id, createdAt: Date.now(), updatedAt: Date.now(), expiresAt: ttlMs ? Date.now() + ttlMs : null, jobs: [], ...payload }; this.sessions.set(id, session); if (profileId) { this.profileIndex.set(profileId, id); } return session; } get(id) { const session = this.sessions.get(id); if (!session) { return null; } if (session.expiresAt && session.expiresAt < Date.now()) { this.delete(id); return null; } return session; } update(id, patch) { const session = this.get(id); if (!session) { return null; } Object.assign(session, patch, { updatedAt: Date.now() }); return session; } attachJob(id, job) { const session = this.get(id); if (!session) { return; } session.jobs.push(job); } clearJobs(id) { const session = this.get(id); if (!session || !Array.isArray(session.jobs)) { return; } session.jobs.forEach((job) => { if (job && typeof job.stop === 'function') { job.stop(); } }); session.jobs = []; } delete(id) { const session = this.sessions.get(id); if (session) { this.clearJobs(id); const profileId = session.profile?.id ? String(session.profile.id) : null; if (profileId && this.profileIndex.get(profileId) === id) { this.profileIndex.delete(profileId); } } this.sessions.delete(id); } list() { return Array.from(this.sessions.values()); } } module.exports = new SessionStore();