| 18 | type SessionSubscriber = (session: SessionData) => void; |
| 19 | |
| 20 | class SessionStore { |
| 21 | private sessions = new Map<string, SessionData>(); |
| 22 | private subscribers = new Map<string, Set<SessionSubscriber>>(); |
| 23 | private cleanupInterval: NodeJS.Timeout | null = null; |
| 24 | |
| 25 | constructor() { |
| 26 | // Start automatic cleanup every 5 minutes |
| 27 | this.startAutoCleanup(); |
| 28 | } |
| 29 | |
| 30 | /** |
| 31 | * Create a new session |
| 32 | */ |
| 33 | createSession(sessionId: string, containerId: string): SessionData { |
| 34 | const session: SessionData = { |
| 35 | sessionId, |
| 36 | containerId, |
| 37 | buildStatus: 'idle', |
| 38 | previewReady: false, |
| 39 | createdAt: Date.now(), |
| 40 | lastActivity: Date.now(), |
| 41 | }; |
| 42 | |
| 43 | this.sessions.set(sessionId, session); |
| 44 | logger.info(`Session created: ${sessionId} (container: ${containerId})`); |
| 45 | |
| 46 | return session; |
| 47 | } |
| 48 | |
| 49 | /** |
| 50 | * Get session data by sessionId |
| 51 | */ |
| 52 | getSession(sessionId: string): SessionData | undefined { |
| 53 | const session = this.sessions.get(sessionId); |
| 54 | if (session) { |
| 55 | // Update last activity |
| 56 | session.lastActivity = Date.now(); |
| 57 | this.sessions.set(sessionId, session); |
| 58 | } |
| 59 | return session; |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Update session data |
| 64 | */ |
| 65 | updateSession(sessionId: string, updates: Partial<SessionData>): void { |
| 66 | const session = this.sessions.get(sessionId); |
| 67 | if (!session) { |
| 68 | logger.warn(`Attempted to update non-existent session: ${sessionId}`); |
| 69 | return; |
| 70 | } |
| 71 | |
| 72 | const updatedSession = { |
| 73 | ...session, |
| 74 | ...updates, |
| 75 | lastActivity: Date.now(), |
| 76 | }; |
| 77 |
nothing calls this directly
no outgoing calls
no test coverage detected