UNPKG

@golemio/pid

Version:
116 lines 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SkipHelper = void 0; const RouteTypeEnums_1 = require("../../../../helpers/RouteTypeEnums"); const RunHelper_1 = require("./RunHelper"); const const_1 = require("./const"); /** Extracts the last numeric sequence from strings like: * Os 1111 -> 1111 * Os 1111 B -> 1111 * Rx 1/1111 A -> 1111 */ const TRIP_NUMBER_REGEX = /(\d+)(?!.*\d)/; class SkipHelper { /** * Used exclusively in transfer boards to skip transfers for the current trip * (i.e., transfers within the vehicle where the transfer board is located) */ static isMatchingTripNumber(departure, tripNumber) { const tripShortName = departure.trip_short_name; if (!tripShortName) { return false; } const lastNumber = tripShortName.match(TRIP_NUMBER_REGEX)?.[1]; return !!lastNumber && lastNumber === tripNumber; } static hasNoDelayInfo(departure) { return !departure.is_delay_available; } /** * Used exclusively in departure boards when skip[]=missing is requested (without untracked) */ static isVehicleMissing(departure, runScheduleMap, untrackedTrips, nowDate = new Date()) { // Not missing if essential trip data is missing or if delay information is available if (!("trip.start_timestamp" in departure) || departure["trip.start_timestamp"] === null || departure.run_number === null || departure.route_id === null || departure.is_delay_available) { return false; } const startTimestamp = new Date(departure["trip.start_timestamp"]); const minutesToStart = (startTimestamp.getTime() - nowDate.getTime()) / 60000; /// Not missing if departure is too far in the future (threshold varies for metro) if (this.isOutsideStartThreshold(minutesToStart, departure.route_type)) { return false; } // Missing if the trip should have already started else if (this.hasAlreadyDeparted(minutesToStart)) { return true; } // Cannot determine missing status without run schedule information const runSchedule = runScheduleMap?.get(RunHelper_1.RunHelper.composeRunId(departure.route_id, departure.run_number)); if (!runSchedule) { return false; } // Not missing if this is the first trip in the run or if trip isn't found const runTripIndex = runSchedule.findIndex((trip) => trip.trip_id === departure.trip_id); if (runTripIndex === -1 || runTripIndex === 0) { return false; } // Not missing if there's a significant gap after the previous trip const previousRunTripEnd = new Date(runSchedule[runTripIndex - 1].end_timestamp); if (this.hasLargeTimegapBetweenTrips(previousRunTripEnd, startTimestamp)) { return false; } // Not missing if the previous trip has delay information available const isPreviousUntracked = untrackedTrips?.has(runSchedule[runTripIndex - 1].trip_id); if (!isPreviousUntracked) { return false; } const previousStartTimestamp = new Date(runSchedule[runTripIndex - 1].start_timestamp); const previousMinutesToStart = (previousStartTimestamp.getTime() - nowDate.getTime()) / 60000; // Missing if previous trip should have already started if (this.hasAlreadyDeparted(previousMinutesToStart)) { return true; } // Check position of previous trip in the run const previousRunTripIndex = runTripIndex - 1; if (previousRunTripIndex === -1 || previousRunTripIndex === 0) { return false; } // Check for gaps before the previous trip const previousPreviousRunTripEnd = new Date(runSchedule[previousRunTripIndex - 1].end_timestamp); if (this.hasLargeTimegapBetweenTrips(previousPreviousRunTripEnd, previousStartTimestamp)) { return false; } // If we reach here, the previous untracked trip is likely missing, // which implies the current trip is also missing return true; } static isTripCanceled(departure) { return !!departure.is_canceled; } static isVehicleAtStop(departure) { if (!("arrival_datetime" in departure)) { return false; } const isAtStop = departure.stop_sequence === departure["trip.last_position.this_stop_sequence"]; const isPassStop = !!departure["trip.last_position.last_stop_sequence"] && departure.stop_sequence <= departure["trip.last_position.last_stop_sequence"]; return isAtStop || isPassStop; } static isOutsideStartThreshold(minutesToStart, routeType) { const isMetro = routeType === RouteTypeEnums_1.GTFSRouteTypeEnum.METRO; return isMetro ? minutesToStart >= const_1.START_SOON_METRO_MINUTES_THRESHOLD : minutesToStart >= const_1.START_SOON_MINUTES_THRESHOLD; } static hasAlreadyDeparted(minutesToStart) { return minutesToStart < const_1.DEPARTURED_MINUTES_THRESHOLD; } static hasLargeTimegapBetweenTrips(endTimestamp, startTimestamp) { const minutesAfterPrevious = (startTimestamp.getTime() - endTimestamp.getTime()) / 60000; return minutesAfterPrevious >= const_1.TRIP_GAP_MINUTES_THRESHOLD; } } exports.SkipHelper = SkipHelper; //# sourceMappingURL=SkipHelper.js.map