RELEASE V5.0.0 : Voici les modifications apportées :
-> IMPLÉMENTATION DONNÉES GTFS / GTFS-RT / SIRI LTE SNCF -> RESTRUCTURATION DE L'APP. FONCTIONNALITÉS EN COURS DE DÉVELOPPEMENT : -> REFONTE DU DESIGN DES AFFICHEURS CLASSIQUES -> AMÉLIORATION DES
This commit is contained in:
1 parent
78e0a0ef7b
commit
1729ab4831
1 file changed
+59
-18
+59
-18
@@ -20,6 +20,20 @@ let siriLiteCache = {
|
||||
updates: new Map()
|
||||
};
|
||||
|
||||
// Helper fetch avec timeout pour ne jamais bloquer l'affichage en cas de réseau lent ou de blocage
|
||||
async function fetchWithTimeout(url, options = {}, timeoutMs = 7000) {
|
||||
const controller = new AbortController();
|
||||
const id = setTimeout(() => controller.abort(), timeoutMs);
|
||||
try {
|
||||
const res = await fetch(url, { ...options, signal: controller.signal });
|
||||
clearTimeout(id);
|
||||
return res;
|
||||
} catch (err) {
|
||||
clearTimeout(id);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function cleanNum(n) {
|
||||
if (!n) return '';
|
||||
const m = String(n).match(/\d+/);
|
||||
@@ -39,8 +53,8 @@ async function fetchSiriLiteData() {
|
||||
const updatesMap = new Map();
|
||||
|
||||
try {
|
||||
const res = await fetch(SNCF_SIRI_LITE_TIMETABLE);
|
||||
if (res.ok) {
|
||||
const res = await fetchWithTimeout(SNCF_SIRI_LITE_TIMETABLE, {}, 8000);
|
||||
if (res && res.ok) {
|
||||
const xml = await res.text();
|
||||
const journeys = xml.split('<EstimatedVehicleJourney>');
|
||||
|
||||
@@ -123,7 +137,7 @@ async function fetchSiriLiteData() {
|
||||
updates: updatesMap
|
||||
};
|
||||
} catch (err) {
|
||||
console.warn('[sncfApi] Notice: SIRI-Lite refresh error:', err);
|
||||
console.warn('[sncfApi] Notice: SIRI-Lite refresh error/timeout:', err);
|
||||
}
|
||||
|
||||
return siriLiteCache;
|
||||
@@ -143,12 +157,12 @@ async function fetchGtfsRealtimeData() {
|
||||
|
||||
try {
|
||||
const [rtRes, alertsRes] = await Promise.allSettled([
|
||||
fetch(SNCF_GTFS_RT_TRIP_UPDATES),
|
||||
fetch(SNCF_GTFS_RT_SERVICE_ALERTS)
|
||||
fetchWithTimeout(SNCF_GTFS_RT_TRIP_UPDATES, {}, 6000),
|
||||
fetchWithTimeout(SNCF_GTFS_RT_SERVICE_ALERTS, {}, 6000)
|
||||
]);
|
||||
|
||||
// 1. Décodage Trip Updates (Retards, Suppressions)
|
||||
if (rtRes.status === 'fulfilled' && rtRes.value.ok) {
|
||||
if (rtRes.status === 'fulfilled' && rtRes.value && rtRes.value.ok) {
|
||||
const buffer = await rtRes.value.arrayBuffer();
|
||||
const feed = transit_realtime.FeedMessage.decode(new Uint8Array(buffer));
|
||||
|
||||
@@ -188,7 +202,7 @@ async function fetchGtfsRealtimeData() {
|
||||
}
|
||||
|
||||
// 2. Décodage Service Alerts (Causes de retards & perturbations)
|
||||
if (alertsRes.status === 'fulfilled' && alertsRes.value.ok) {
|
||||
if (alertsRes.status === 'fulfilled' && alertsRes.value && alertsRes.value.ok) {
|
||||
const buffer = await alertsRes.value.arrayBuffer();
|
||||
const alertFeed = transit_realtime.FeedMessage.decode(new Uint8Array(buffer));
|
||||
|
||||
@@ -294,13 +308,29 @@ async function fetchGtfsStationTimetable(uic, mode = 'departs') {
|
||||
if (!uic) return null;
|
||||
|
||||
try {
|
||||
const publicUrl = (typeof process !== 'undefined' && process.env && process.env.PUBLIC_URL) ? process.env.PUBLIC_URL : '';
|
||||
const stationUrl = `${publicUrl}/data/stations/${uic}.json`;
|
||||
|
||||
// Chargement parallèle tolérant aux pannes réseau / CORS
|
||||
const [jsonRes, rtData, siriData] = await Promise.all([
|
||||
fetch(`/data/stations/${uic}.json`),
|
||||
fetchGtfsRealtimeData(),
|
||||
fetchSiriLiteData()
|
||||
fetch(stationUrl).catch(err => {
|
||||
console.warn(`[sncfApi] Notice: fetch station ${uic} error:`, err);
|
||||
return null;
|
||||
}),
|
||||
fetchGtfsRealtimeData().catch(err => {
|
||||
console.warn('[sncfApi] Notice: GTFS-RT error:', err);
|
||||
return { updates: new Map(), alerts: [] };
|
||||
}),
|
||||
fetchSiriLiteData().catch(err => {
|
||||
console.warn('[sncfApi] Notice: SIRI-Lite error:', err);
|
||||
return { platforms: new Map(), updates: new Map() };
|
||||
})
|
||||
]);
|
||||
|
||||
if (!jsonRes.ok) return null;
|
||||
if (!jsonRes || !jsonRes.ok) {
|
||||
console.warn(`[sncfApi] Fichier de gare introuvable : ${stationUrl} (statut : ${jsonRes ? jsonRes.status : 'réseau bloqué'})`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = await jsonRes.json();
|
||||
const rawList = mode === 'arrivees' ? data.arrivees : data.departs;
|
||||
@@ -311,19 +341,19 @@ async function fetchGtfsStationTimetable(uic, mode = 'departs') {
|
||||
const currentDay = now.getDay(); // 0 = Dimanche, 1 = Lundi, ..., 6 = Samedi
|
||||
const currentYYYYMMDD = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}`;
|
||||
|
||||
// Filtrage complet de circulation GTFS
|
||||
const circulatingList = rawList.filter(t => {
|
||||
// 1. Si la date courante figure dans les dates explicites
|
||||
// 1. Filtrage précis par date GTFS (si la date du jour est dans la plage de validité)
|
||||
let circulatingList = rawList.filter(t => {
|
||||
// Si la date courante figure dans les dates explicites
|
||||
if (Array.isArray(t.dates) && t.dates.length > 0 && t.dates.includes(currentYYYYMMDD)) {
|
||||
return true;
|
||||
}
|
||||
// 2. Si le jour de la semaine est actif dans la période de validité
|
||||
// Si le jour de la semaine est actif dans la période de validité
|
||||
if (Array.isArray(t.days) && t.days.length > 0 && t.days.includes(currentDay)) {
|
||||
if ((!t.start || currentYYYYMMDD >= t.start) && (!t.end || currentYYYYMMDD <= t.end)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 3. Train de nuit parti la veille et arrivant aujourd'hui (heures >= 24h)
|
||||
// Train de nuit parti la veille et arrivant aujourd'hui (heures >= 24h)
|
||||
if (Array.isArray(t.days) && t.days.length > 0) {
|
||||
const prevDay = (currentDay + 6) % 7;
|
||||
const rawTime = mode === 'arrivees' ? (t.arr || t.dep) : (t.dep || t.arr);
|
||||
@@ -333,13 +363,24 @@ async function fetchGtfsStationTimetable(uic, mode = 'departs') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 4. Si aucune règle n'est renseignée
|
||||
// Si aucune règle n'est renseignée
|
||||
if (!t.dates?.length && !t.days?.length) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
// 2. Fallback robuste : si la date actuelle est hors calendrier GTFS, filtrer par jour de la semaine
|
||||
if (circulatingList.length === 0) {
|
||||
return [];
|
||||
circulatingList = rawList.filter(t => {
|
||||
if (Array.isArray(t.days) && t.days.length > 0) {
|
||||
return t.days.includes(currentDay);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Fallback complet : si toujours vide, renvoyer la grille quotidienne complète
|
||||
if (circulatingList.length === 0) {
|
||||
circulatingList = rawList;
|
||||
}
|
||||
|
||||
// Helper de résolution ultra-robuste de quai par couple (train, gare)
|
||||
|
||||
Reference in new issue
Block a user