@golemio/pid
Version:
Golemio PID Module
131 lines • 6.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DepartureBoardFacade = void 0;
const RouteTypeEnums_1 = require("../../../../helpers/RouteTypeEnums");
const trace_provider_1 = require("@golemio/core/dist/monitoring/opentelemetry/trace-provider");
const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors");
const DepartureGroupRefiner_1 = require("../helpers/DepartureGroupRefiner");
const PublicDepartureTransformation_1 = require("../transformations/PublicDepartureTransformation");
class DepartureBoardFacade {
constructor(departureRepository, tripRepository, stopTimeRepository, descriptorRepository) {
this.departureRepository = departureRepository;
this.tripRepository = tripRepository;
this.stopTimeRepository = stopTimeRepository;
this.descriptorRepository = descriptorRepository;
this.transformation = new PublicDepartureTransformation_1.PublicDepartureTransformation();
}
async getAll(stopIds, limit, routeShortNames, minutesAfter) {
let output;
const sortedStopGroups = this.sortStopGroupsByPriority(stopIds);
const promises = sortedStopGroups.map(async (stopGroup) => await this.handleStopGroupDepartures(stopGroup, limit, routeShortNames, minutesAfter));
try {
output = await Promise.all(promises);
}
catch (err) {
if (err instanceof golemio_errors_1.AbstractGolemioError) {
throw err;
}
throw new golemio_errors_1.GeneralError("Error while retrieving cached data", this.constructor.name, err, 500);
}
if (output.every((value) => value === null)) {
return null;
}
else {
return output.map((value) => {
if (value === null) {
return [];
}
else {
return value;
}
});
}
}
async handleStopGroupDepartures(stopGroup, limit, routeShortNames, minutesAfter) {
let outputGroup = [];
const spanDepartures = (0, trace_provider_1.createChildSpan)(`Departures.${stopGroup.priority}.getPublicDepartureCache`);
const departures = await this.departureRepository.getPublicGtfsDepartureCache(stopGroup.stopIds, minutesAfter);
spanDepartures?.end();
if (departures.length === 0) {
return null;
}
const spanPositions = (0, trace_provider_1.createChildSpan)(`Departures.${stopGroup.priority}.getAllVehiclePositions`);
const positionsByTrip = await this.tripRepository.getAllVehiclePositionsForMultipleTrips(departures.map((departure) => departure.trip_id));
spanPositions?.end();
const spanTransform = (0, trace_provider_1.createChildSpan)(`Departures.${stopGroup.priority}.transformDepartures`);
try {
for (const departure of departures) {
if (Object.keys(departure).length === 0) {
continue;
}
const positions = positionsByTrip.get(departure.trip_id) ?? [];
const duplicatedDepartures = await this.duplicateDeparturesWithDifferentVehicleIds(departure, positions);
outputGroup = outputGroup.concat(duplicatedDepartures);
}
}
catch (err) {
if (err instanceof golemio_errors_1.AbstractGolemioError) {
throw err;
}
throw new golemio_errors_1.GeneralError("Error while retrieving cached data", this.constructor.name, err, 500);
}
finally {
spanTransform?.end();
}
const spanManipulate = (0, trace_provider_1.createChildSpan)(`Departures.${stopGroup.priority}.manipulateDepartures`);
try {
outputGroup = DepartureGroupRefiner_1.DepartureGroupRefiner.filterDeparturesByRouteShortNames(outputGroup, routeShortNames);
outputGroup = DepartureGroupRefiner_1.DepartureGroupRefiner.sortDeparturesByPredictedTimestamp(outputGroup);
// minutesBefore is set to 0 because we want to display departures that are already happening
// this may change in the future
outputGroup = DepartureGroupRefiner_1.DepartureGroupRefiner.removeDeparturesOutsideTimeRange(outputGroup, 0, minutesAfter).slice(0, limit);
}
catch (err) {
throw new golemio_errors_1.GeneralError("Error while manipulating departures", this.constructor.name, err, 500);
}
finally {
spanManipulate?.end();
}
return outputGroup;
}
async duplicateDeparturesWithDifferentVehicleIds(departure, vehiclePositions) {
const outputGroup = [];
// If there are no RT data, we still want to display the departure
// but without any RT/vehicle information
if (vehiclePositions.length === 0) {
outputGroup.push(this.transformation.transformElement({
departure,
vehiclePosition: null,
vehicleDescriptor: null,
stopTime: null,
}));
return outputGroup;
}
// Otherwise, we want to duplicate the departure for each vehicleId
// (multiple vehicles can be on the same trip at the same time)
for (const vehiclePosition of vehiclePositions) {
const vehicleDescriptor = vehiclePosition?.detailed_info.registration_number
? await this.descriptorRepository.getOneByRegNumber(departure.route_type, vehiclePosition?.detailed_info.registration_number)
: null;
let currentStopTime = null;
// If the vehicle is a train, we need to get the current stop time
// to later determine the RT CIS platform code (trains don't have platform codes in GTFS)
if (vehiclePosition.route_type === RouteTypeEnums_1.GTFSRouteTypeEnum.TRAIN) {
const stopTimes = await this.stopTimeRepository.getPublicStopTimeCache(vehiclePosition.vehicle_id, departure.trip_id);
currentStopTime = stopTimes.find((stopTime) => stopTime.sequence === departure.stop_sequence) ?? null;
}
outputGroup.push(this.transformation.transformElement({
departure,
vehiclePosition,
vehicleDescriptor,
stopTime: currentStopTime,
}));
}
return outputGroup;
}
sortStopGroupsByPriority(stopIds) {
return Array.from(stopIds).sort((a, b) => a.priority - b.priority);
}
}
exports.DepartureBoardFacade = DepartureBoardFacade;
//# sourceMappingURL=DepartureBoardFacade.js.map