Ensure shuttle repository uses typed EventEmitter overrides

This commit is contained in:
2025-10-10 19:56:19 -07:00
parent a2f074b150
commit 4db517d4c0
4 changed files with 132 additions and 51 deletions

View File

@@ -1,21 +1,76 @@
import EventEmitter from "node:events";
import { ShuttleGetterSetterRepository } from "./ShuttleGetterSetterRepository";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../../entities/ShuttleRepositoryEntities";
import { IEntityWithId } from "../../entities/SharedEntities";
import {
ShuttleRepositoryEvent,
ShuttleRepositoryEventListener,
ShuttleRepositoryEventName,
ShuttleRepositoryEventPayloads,
} from "./ShuttleGetterRepository";
/**
* An unoptimized in memory repository.
* (I would optimize it with actual data structures, but I'm
* switching to another data store later anyways)
*/
export class UnoptimizedInMemoryShuttleRepository implements ShuttleGetterSetterRepository {
export class UnoptimizedInMemoryShuttleRepository
extends EventEmitter
implements ShuttleGetterSetterRepository {
public override on<T extends ShuttleRepositoryEventName>(
event: T,
listener: ShuttleRepositoryEventListener<T>,
): this;
public override on(event: string | symbol, listener: (...args: any[]) => void): this {
return super.on(event, listener);
}
public override once<T extends ShuttleRepositoryEventName>(
event: T,
listener: ShuttleRepositoryEventListener<T>,
): this;
public override once(event: string | symbol, listener: (...args: any[]) => void): this {
return super.once(event, listener);
}
public override off<T extends ShuttleRepositoryEventName>(
event: T,
listener: ShuttleRepositoryEventListener<T>,
): this;
public override off(event: string | symbol, listener: (...args: any[]) => void): this {
return super.off(event, listener);
}
public override addListener<T extends ShuttleRepositoryEventName>(
event: T,
listener: ShuttleRepositoryEventListener<T>,
): this;
public override addListener(event: string | symbol, listener: (...args: any[]) => void): this {
return super.addListener(event, listener);
}
public override removeListener<T extends ShuttleRepositoryEventName>(
event: T,
listener: ShuttleRepositoryEventListener<T>,
): this;
public override removeListener(event: string | symbol, listener: (...args: any[]) => void): this {
return super.removeListener(event, listener);
}
public override emit<T extends ShuttleRepositoryEventName>(
event: T,
payload: ShuttleRepositoryEventPayloads[T],
): boolean;
public override emit(event: string | symbol, ...args: any[]): boolean {
return super.emit(event, ...args);
}
private stops: IStop[] = [];
private routes: IRoute[] = [];
private shuttles: IShuttle[] = [];
private etas: IEta[] = [];
private orderedStops: IOrderedStop[] = [];
private subscribers: ((eta: IEta) => void)[] = [];
public async getStops(): Promise<IStop[]> {
return this.stops;
}
@@ -52,17 +107,6 @@ export class UnoptimizedInMemoryShuttleRepository implements ShuttleGetterSetter
return this.etas.filter(eta => eta.stopId === stopId);
}
public subscribeToEtaUpdates(listener: (eta: IEta) => void) {
this.subscribers.push(listener);
}
public unsubscribeFromEtaUpdates(listener: (eta: IEta) => void) {
const index = this.subscribers.findIndex((existingListener) => existingListener == listener);
if (index >= 0) {
this.subscribers.splice(index, 1);
}
}
public async getEtaForShuttleAndStopId(shuttleId: string, stopId: string) {
return this.findEntityByMatcher<IEta>((value) => value.stopId === stopId && value.shuttleId === shuttleId, this.etas);
}
@@ -134,13 +178,7 @@ export class UnoptimizedInMemoryShuttleRepository implements ShuttleGetterSetter
} else {
this.etas.push(eta);
}
this.publishEtaUpdateToSubscribers(eta);
}
private publishEtaUpdateToSubscribers(eta: IEta) {
this.subscribers.forEach(subscriber => {
subscriber(eta);
});
this.emit(ShuttleRepositoryEvent.ETA_UPDATED, eta);
}
private async removeEntityByMatcherIfExists<T>(callback: (value: T) => boolean, arrayToSearchIn: T[]) {
@@ -178,10 +216,14 @@ export class UnoptimizedInMemoryShuttleRepository implements ShuttleGetterSetter
}
public async removeEtaIfExists(shuttleId: string, stopId: string): Promise<IEta | null> {
return await this.removeEntityByMatcherIfExists((eta) => {
const removedEta = await this.removeEntityByMatcherIfExists((eta) => {
return eta.stopId === stopId
&& eta.shuttleId === shuttleId
}, this.etas);
if (removedEta) {
this.emit(ShuttleRepositoryEvent.ETA_REMOVED, removedEta);
}
return removedEta;
}
public async clearShuttleData(): Promise<void> {
@@ -189,7 +231,9 @@ export class UnoptimizedInMemoryShuttleRepository implements ShuttleGetterSetter
}
public async clearEtaData(): Promise<void> {
const removedEtas = [...this.etas];
this.etas = [];
this.emit(ShuttleRepositoryEvent.ETA_DATA_CLEARED, removedEtas);
}
public async clearOrderedStopData(): Promise<void> {