UNPKG

@golemio/pid

Version:
131 lines • 6.74 kB
"use strict"; 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