import { Session } from './session.js'; /** * Store handles active in-memory sessions indexed by session ID. * It also maintains a ride ID mapping to prevent duplicate active sessions per ride. */ export class Store { constructor() { this.sessions = new Map(); // key: sessionID, value: Session this.rideToSession = new Map(); // key: rideID, value: Session } /** * Retrieves a session by its session ID. * @param {string} sessionID * @returns {Session|undefined} */ getSession(sessionID) { return this.sessions.get(sessionID); } /** * Retrieves an active session by its ride ID. * @param {string} rideID * @returns {Session|undefined} */ getSessionByRide(rideID) { return this.rideToSession.get(rideID); } /** * Registers a new call session, checking for active duplicates. * @param {string} rideID * @param {string} driverID * @param {string} passengerID * @param {number} durationMs * @param {string} [driverIP] * @param {string} [passengerIP] * @returns {Session} * @throws {Error} Throws if an active session already exists for the ride */ createSession(rideID, driverID, passengerID, durationMs, driverIP = null, passengerIP = null) { const existing = this.rideToSession.get(rideID); if (existing && existing.status !== 'ended') { throw new Error('session_exists'); } const sess = new Session(rideID, driverID, passengerID, durationMs, driverIP, passengerIP); this.sessions.set(sess.sessionID, sess); this.rideToSession.set(rideID, sess); return sess; } /** * Removes a session from registry mappings. * @param {string} sessionID */ destroySession(sessionID) { const sess = this.sessions.get(sessionID); if (sess) { this.sessions.delete(sessionID); this.rideToSession.delete(sess.rideID); } } /** * Finds expired active sessions. * @returns {Session[]} */ getExpiredSessions() { const expired = []; const now = Date.now(); for (const sess of this.sessions.values()) { if (sess.status !== 'ended' && now > sess.expiresAt.getTime()) { expired.push(sess); } } return expired; } /** * Returns active sessions count. * @returns {number} */ getActiveCount() { return this.sessions.size; } }