import { IEta } from "../../../entities/ShuttleRepositoryEntities"; import { BaseRedisRepository } from "../../BaseRedisRepository"; import { ETAGetterRepository, ETARepositoryEventListener, ETARepositoryEventName } from "./ETAGetterRepository"; export abstract class BaseRedisETARepository extends BaseRedisRepository implements ETAGetterRepository { private static readonly ETA_KEY_PREFIX = 'shuttle:eta:'; // Helper methods private createEtaKey = (shuttleId: string, stopId: string) => `${BaseRedisETARepository.ETA_KEY_PREFIX}${shuttleId}:${stopId}`; createRedisHashFromEta = (eta: IEta): Record => ({ secondsRemaining: eta.secondsRemaining.toString(), shuttleId: eta.shuttleId, stopId: eta.stopId, systemId: eta.systemId, updatedTime: eta.updatedTime.toISOString(), }); createEtaFromRedisData = (data: Record): IEta => ({ secondsRemaining: parseFloat(data.secondsRemaining), shuttleId: data.shuttleId, stopId: data.stopId, systemId: data.systemId, updatedTime: new Date(data.updatedTime), }); // Getter implementations async getEtasForShuttleId(shuttleId: string): Promise { const keys = await this.redisClient.keys(`${BaseRedisETARepository.ETA_KEY_PREFIX}${shuttleId}:*`); const etas: IEta[] = []; for (const key of keys) { const data = await this.redisClient.hGetAll(key); if (Object.keys(data).length > 0) { etas.push(this.createEtaFromRedisData(data)); } } return etas; } async getEtasForStopId(stopId: string): Promise { const keys = await this.redisClient.keys(`${BaseRedisETARepository.ETA_KEY_PREFIX}*`); const etas: IEta[] = []; for (const key of keys) { const data = await this.redisClient.hGetAll(key); if (Object.keys(data).length > 0 && data.stopId === stopId) { etas.push(this.createEtaFromRedisData(data)); } } return etas; } async getEtaForShuttleAndStopId(shuttleId: string, stopId: string): Promise { const key = this.createEtaKey(shuttleId, stopId); const data = await this.redisClient.hGetAll(key); if (Object.keys(data).length === 0) { return null; } return this.createEtaFromRedisData(data); } // EventEmitter override methods for type safety override on( event: T, listener: ETARepositoryEventListener, ): this; override on(event: string | symbol, listener: (...args: any[]) => void): this { return super.on(event, listener); } override once( event: T, listener: ETARepositoryEventListener, ): this; override once(event: string | symbol, listener: (...args: any[]) => void): this { return super.once(event, listener); } override off( event: T, listener: ETARepositoryEventListener, ): this; override off(event: string | symbol, listener: (...args: any[]) => void): this { return super.off(event, listener); } override addListener( event: T, listener: ETARepositoryEventListener, ): this; override addListener(event: string | symbol, listener: (...args: any[]) => void): this { return super.addListener(event, listener); } override removeListener( event: T, listener: ETARepositoryEventListener, ): this; override removeListener(event: string | symbol, listener: (...args: any[]) => void): this { return super.removeListener(event, listener); } override removeAllListeners(eventName?: string | symbol): this { return super.removeAllListeners(eventName); } }