const tam = require("./sources/tam"); const network = require("./network.json"); // Time at which the course data needs to be updated next let nextUpdate = null; // Current information about courses let currentCourses = null; /** * Information about the course of a vehicle. * @typedef {Object} Course * @property {string} id Unique identifier for this course. * @property {string} line Transport line number. * @property {string} finalStop Final stop to which the course is headed. * @property {Array.} nextPassings Next stations to which * the vehicle will stop, associated to the passing timestamp, ordered by * increasing passing timestamp. */ /** * Fetch real-time information about active courses in the TaM network. * * New data will only be fetched from the TaM server once every minute, * otherwise pulling from the in-memory cache. * @returns {Object.} Mapping from active course IDs to * information about each course. */ const fetch = async() => { if (nextUpdate === null || Date.now() >= nextUpdate) { const courses = {}; const passings = tam.fetchRealtime(); const timing = (await passings.next()).value; nextUpdate = timing.nextUpdate; // Aggregate passings relative to the same course for await (const passing of passings) { const { course: id, routeShortName: line, stopId, destArCode: finalStop } = passing; const arrivalTime = ( timing.lastUpdate + parseInt(passing.delaySec, 10) * 1000 ); if (!(id in courses)) { courses[id] = { id, line, finalStop, nextPassings: [[stopId, arrivalTime]] }; } else { courses[id].nextPassings.push([stopId, arrivalTime]); } } // Filter courses to only keep those referring to known data for (const courseId of Object.keys(courses)) { const course = courses[courseId]; if (!(course.line in network.lines)) { delete courses[courseId]; } else { for (const [stopId,] of course.nextPassings) { if (!(stopId in network.stops)) { delete courses[courseId]; break; } } } } // Order next passings by increasing passing time for (const courseId of Object.keys(courses)) { courses[courseId].nextPassings.sort( ([, time1], [, time2]) => time1 - time2 ); } currentCourses = courses; } return currentCourses; }; exports.fetch = fetch;