From 42cd34e755a594d3853c117df3900c1e9b03a74e Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 11 Nov 2025 15:16:21 -0800 Subject: [PATCH] Update InterchangeSystem and caller to construct an ETA repository based on argumetns --- src/entities/InterchangeSystem.ts | 68 ++++++++++++++++++++++++++----- src/index.ts | 1 + 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/entities/InterchangeSystem.ts b/src/entities/InterchangeSystem.ts index 03cac46..49ec992 100644 --- a/src/entities/InterchangeSystem.ts +++ b/src/entities/InterchangeSystem.ts @@ -16,6 +16,11 @@ import { import { RedisParkingRepository } from "../repositories/parking/RedisParkingRepository"; import { RedisShuttleRepository } from "../repositories/shuttle/RedisShuttleRepository"; import { ShuttleGetterRepository } from "../repositories/shuttle/ShuttleGetterRepository"; +import { InMemoryExternalSourceETARepository } from "../repositories/shuttle/eta/InMemoryExternalSourceETARepository"; +import { ETAGetterRepository } from "../repositories/shuttle/eta/ETAGetterRepository"; +import { RedisSelfUpdatingETARepository } from "../repositories/shuttle/eta/RedisSelfUpdatingETARepository"; +import { RedisExternalSourceETARepository } from "../repositories/shuttle/eta/RedisExternalSourceETARepository"; +import { InMemorySelfUpdatingETARepository } from "../repositories/shuttle/eta/InMemorySelfUpdatingETARepository"; export interface InterchangeSystemBuilderArguments { name: string; @@ -34,6 +39,12 @@ export interface InterchangeSystemBuilderArguments { * ID for the parking repository ID in the codebase. */ parkingSystemId?: string; + + /** + * Controls whether to self-calculate ETAs or use the external + * shuttle provider for them. + */ + useSelfUpdatingEtas: boolean } export class InterchangeSystem { @@ -42,6 +53,7 @@ export class InterchangeSystem { public id: string, public shuttleTimedDataLoader: TimedApiBasedRepositoryLoader, public shuttleRepository: ShuttleGetterSetterRepository, + public etaRepository: ETAGetterRepository, public notificationScheduler: ETANotificationScheduler, public notificationRepository: NotificationRepository, public parkingTimedDataLoader: TimedApiBasedRepositoryLoader | null, @@ -57,10 +69,14 @@ export class InterchangeSystem { static async build( args: InterchangeSystemBuilderArguments, ) { - const { shuttleRepository, timedShuttleDataLoader } = await InterchangeSystem.buildRedisShuttleLoaderAndRepository(args); + const { shuttleRepository, timedShuttleDataLoader, etaRepository } = await InterchangeSystem.buildRedisShuttleLoaderAndRepositories(args); timedShuttleDataLoader.start(); - const { notificationScheduler, notificationRepository } = await InterchangeSystem.buildNotificationSchedulerAndRepository(shuttleRepository, args); + const { notificationScheduler, notificationRepository } = await InterchangeSystem.buildNotificationSchedulerAndRepository( + etaRepository, + shuttleRepository, + args + ); notificationScheduler.startListeningForUpdates(); let { parkingRepository, timedParkingLoader } = await InterchangeSystem.buildRedisParkingLoaderAndRepository(args.parkingSystemId); @@ -71,6 +87,7 @@ export class InterchangeSystem { args.id, timedShuttleDataLoader, shuttleRepository, + etaRepository, notificationScheduler, notificationRepository, timedParkingLoader, @@ -78,7 +95,7 @@ export class InterchangeSystem { ); } - private static async buildRedisShuttleLoaderAndRepository(args: InterchangeSystemBuilderArguments) { + private static async buildRedisShuttleLoaderAndRepositories(args: InterchangeSystemBuilderArguments) { const shuttleRepository = new RedisShuttleRepository(); await shuttleRepository.connect(); const shuttleDataLoader = new ApiBasedShuttleRepositoryLoader( @@ -89,13 +106,26 @@ export class InterchangeSystem { const timedShuttleDataLoader = new TimedApiBasedRepositoryLoader( shuttleDataLoader ); - return { shuttleRepository, timedShuttleDataLoader }; + + let etaRepository: ETAGetterRepository; + if (args.useSelfUpdatingEtas) { + etaRepository = new RedisSelfUpdatingETARepository(shuttleRepository); + } else { + etaRepository = new RedisExternalSourceETARepository(); + } + + return { shuttleRepository, etaRepository, timedShuttleDataLoader }; } - private static async buildNotificationSchedulerAndRepository(shuttleRepository: ShuttleGetterRepository, args: InterchangeSystemBuilderArguments) { + private static async buildNotificationSchedulerAndRepository( + etaRepository: ETAGetterRepository, + shuttleRepository: ShuttleGetterRepository, + args: InterchangeSystemBuilderArguments + ) { const notificationRepository = new RedisNotificationRepository(); await notificationRepository.connect(); const notificationScheduler = new ETANotificationScheduler( + etaRepository, shuttleRepository, notificationRepository, new AppleNotificationSender(), @@ -138,10 +168,14 @@ export class InterchangeSystem { static buildForTesting( args: InterchangeSystemBuilderArguments, ) { - const { shuttleRepository, timedShuttleLoader } = InterchangeSystem.buildInMemoryShuttleLoaderAndRepository(args); + const { shuttleRepository, timedShuttleLoader, etaRepository } = InterchangeSystem.buildInMemoryShuttleLoaderAndRepositories(args); // Timed shuttle loader is not started here - const { notificationScheduler, notificationRepository } = InterchangeSystem.buildInMemoryNotificationSchedulerAndRepository(shuttleRepository, args); + const { notificationScheduler, notificationRepository } = InterchangeSystem.buildInMemoryNotificationSchedulerAndRepository( + etaRepository, + shuttleRepository, + args + ); notificationScheduler.startListeningForUpdates(); let { parkingRepository, timedParkingLoader } = this.buildInMemoryParkingLoaderAndRepository(args.parkingSystemId); @@ -152,6 +186,7 @@ export class InterchangeSystem { args.id, timedShuttleLoader, shuttleRepository, + etaRepository, notificationScheduler, notificationRepository, timedParkingLoader, @@ -159,9 +194,14 @@ export class InterchangeSystem { ); } - private static buildInMemoryNotificationSchedulerAndRepository(shuttleRepository: UnoptimizedInMemoryShuttleRepository, args: InterchangeSystemBuilderArguments) { + private static buildInMemoryNotificationSchedulerAndRepository( + etaRepository: ETAGetterRepository, + shuttleRepository: UnoptimizedInMemoryShuttleRepository, + args: InterchangeSystemBuilderArguments + ) { const notificationRepository = new InMemoryNotificationRepository(); const notificationScheduler = new ETANotificationScheduler( + etaRepository, shuttleRepository, notificationRepository, new AppleNotificationSender(false), @@ -193,7 +233,7 @@ export class InterchangeSystem { return { parkingRepository, timedParkingLoader }; } - private static buildInMemoryShuttleLoaderAndRepository(args: InterchangeSystemBuilderArguments) { + private static buildInMemoryShuttleLoaderAndRepositories(args: InterchangeSystemBuilderArguments) { const shuttleRepository = new UnoptimizedInMemoryShuttleRepository(); const shuttleDataLoader = new ApiBasedShuttleRepositoryLoader( args.passioSystemId, @@ -205,7 +245,15 @@ export class InterchangeSystem { const timedShuttleLoader = new TimedApiBasedRepositoryLoader( shuttleDataLoader ); - return { shuttleRepository, timedShuttleLoader }; + + let etaRepository: ETAGetterRepository; + if (args.useSelfUpdatingEtas) { + etaRepository = new InMemorySelfUpdatingETARepository(shuttleRepository); + } else { + etaRepository = new InMemoryExternalSourceETARepository(); + } + + return { shuttleRepository, etaRepository, timedShuttleLoader }; } } diff --git a/src/index.ts b/src/index.ts index bcc32a9..a8fd797 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,7 @@ const supportedSystems: InterchangeSystemBuilderArguments[] = [ passioSystemId: "263", parkingSystemId: ChapmanApiBasedParkingRepositoryLoader.id, name: "Chapman University", + useSelfUpdatingEtas: true, } ]