Guard satellite target refreshes

This commit is contained in:
James Smith
2026-03-19 19:12:51 +00:00
parent 8caec74c5c
commit 080464de98
+38 -27
View File
@@ -787,6 +787,7 @@
let packetConsoleCollapsed = false; let packetConsoleCollapsed = false;
let _dashboardRetryTimer = null; let _dashboardRetryTimer = null;
let _dashboardRetryAttempts = 0; let _dashboardRetryAttempts = 0;
let _satelliteSelectionRequestToken = 0;
const passCache = new Map(); const passCache = new Map();
const telemetryCache = new Map(); const telemetryCache = new Map();
const transmitterCache = new Map(); const transmitterCache = new Map();
@@ -1050,8 +1051,10 @@
} }
} }
function restoreSatelliteStateFromCache() { function restoreSatelliteStateFromCache(noradId = selectedSatellite) {
const cachedPasses = getCachedPasses(selectedSatellite); if (noradId !== selectedSatellite) return;
const cachedPasses = getCachedPasses(noradId);
if (cachedPasses?.passes?.length) { if (cachedPasses?.passes?.length) {
passes = cachedPasses.passes; passes = cachedPasses.passes;
renderPassList(); renderPassList();
@@ -1064,12 +1067,12 @@
} }
} }
const cachedTelemetry = getCachedLivePosition(selectedSatellite); const cachedTelemetry = getCachedLivePosition(noradId);
if (cachedTelemetry?.position) { if (cachedTelemetry?.position) {
applyTelemetryPosition(cachedTelemetry.position); applyTelemetryPosition(cachedTelemetry.position, { noradId });
} }
const cachedTransmitters = getCachedTransmitters(selectedSatellite); const cachedTransmitters = getCachedTransmitters(noradId);
if (cachedTransmitters?.transmitters?.length) { if (cachedTransmitters?.transmitters?.length) {
renderTransmitters(cachedTransmitters.transmitters); renderTransmitters(cachedTransmitters.transmitters);
} }
@@ -1119,12 +1122,13 @@
select.value = '25544'; select.value = '25544';
} }
selectedSatellite = parseInt(select.value); selectedSatellite = parseInt(select.value);
_satelliteSelectionRequestToken += 1;
clearTelemetry(); clearTelemetry();
restoreSatelliteStateFromCache(); restoreSatelliteStateFromCache(selectedSatellite);
updateMissionDrawerInfo(); updateMissionDrawerInfo();
loadTransmitters(selectedSatellite); loadTransmitters(selectedSatellite, _satelliteSelectionRequestToken);
calculatePasses(); calculatePasses(selectedSatellite, _satelliteSelectionRequestToken);
fetchCurrentTelemetry(); fetchCurrentTelemetry(selectedSatellite, _satelliteSelectionRequestToken);
if (window.gsLoadOutputs) window.gsLoadOutputs(); if (window.gsLoadOutputs) window.gsLoadOutputs();
if (window.gsOnSatelliteChange) window.gsOnSatelliteChange(); if (window.gsOnSatelliteChange) window.gsOnSatelliteChange();
if (!trackedSatelliteCatalog.length) { if (!trackedSatelliteCatalog.length) {
@@ -1149,9 +1153,9 @@
})); }));
renderTrackedSatelliteCatalog(); renderTrackedSatelliteCatalog();
} }
calculatePasses(); calculatePasses(selectedSatellite, _satelliteSelectionRequestToken);
fetchCurrentTelemetry(); fetchCurrentTelemetry(selectedSatellite, _satelliteSelectionRequestToken);
loadTransmitters(selectedSatellite); loadTransmitters(selectedSatellite, _satelliteSelectionRequestToken);
scheduleDashboardDataRetry(2500); scheduleDashboardDataRetry(2500);
}) })
.finally(() => { .finally(() => {
@@ -1162,6 +1166,7 @@
function onSatelliteChange() { function onSatelliteChange() {
const select = document.getElementById('satSelect'); const select = document.getElementById('satSelect');
selectedSatellite = parseInt(select.value); selectedSatellite = parseInt(select.value);
_satelliteSelectionRequestToken += 1;
const satName = satellites[selectedSatellite]?.name || 'Unknown'; const satName = satellites[selectedSatellite]?.name || 'Unknown';
document.getElementById('trackingStatus').textContent = 'ACQUIRING'; document.getElementById('trackingStatus').textContent = 'ACQUIRING';
@@ -1184,11 +1189,11 @@
clearTelemetry(); clearTelemetry();
updateMapTrackSummary(); updateMapTrackSummary();
restoreSatelliteStateFromCache(); restoreSatelliteStateFromCache(selectedSatellite);
updateMissionDrawerInfo(); updateMissionDrawerInfo();
loadTransmitters(selectedSatellite); loadTransmitters(selectedSatellite, _satelliteSelectionRequestToken);
calculatePasses(); calculatePasses(selectedSatellite, _satelliteSelectionRequestToken);
fetchCurrentTelemetry(); fetchCurrentTelemetry(selectedSatellite, _satelliteSelectionRequestToken);
if (window.gsLoadOutputs) window.gsLoadOutputs(); if (window.gsLoadOutputs) window.gsLoadOutputs();
if (window.gsOnSatelliteChange) gsOnSatelliteChange(); if (window.gsOnSatelliteChange) gsOnSatelliteChange();
_dashboardRetryAttempts = 0; _dashboardRetryAttempts = 0;
@@ -1299,11 +1304,10 @@
if (telDist) telDist.textContent = '---- km'; if (telDist) telDist.textContent = '---- km';
} }
async function fetchCurrentTelemetry() { async function fetchCurrentTelemetry(requestedSatellite = selectedSatellite, selectionToken = _satelliteSelectionRequestToken) {
const lat = parseFloat(document.getElementById('obsLat')?.value); const lat = parseFloat(document.getElementById('obsLat')?.value);
const lon = parseFloat(document.getElementById('obsLon')?.value); const lon = parseFloat(document.getElementById('obsLon')?.value);
if (!Number.isFinite(lat) || !Number.isFinite(lon) || !selectedSatellite) return; if (!Number.isFinite(lat) || !Number.isFinite(lon) || !selectedSatellite) return;
const requestedSatellite = selectedSatellite;
const requestKey = `telemetry:${requestedSatellite}:${lat.toFixed(3)}:${lon.toFixed(3)}`; const requestKey = `telemetry:${requestedSatellite}:${lat.toFixed(3)}:${lon.toFixed(3)}`;
if (_telemetryAbortController && _activeTelemetryRequestKey === requestKey) { if (_telemetryAbortController && _activeTelemetryRequestKey === requestKey) {
@@ -1342,7 +1346,7 @@
const pos = data.positions.find(p => parseInt(p.norad_id, 10) === requestedSatellite) || null; const pos = data.positions.find(p => parseInt(p.norad_id, 10) === requestedSatellite) || null;
if (!pos) return; if (!pos) return;
cacheLivePosition(requestedSatellite, pos); cacheLivePosition(requestedSatellite, pos);
if (requestedSatellite !== selectedSatellite) return; if (selectionToken !== _satelliteSelectionRequestToken || requestedSatellite !== selectedSatellite) return;
handleLivePositions(data.positions); handleLivePositions(data.positions);
} catch (_) { } catch (_) {
if (_telemetryAbortController?.signal?.aborted) { if (_telemetryAbortController?.signal?.aborted) {
@@ -1640,6 +1644,7 @@
}); });
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
_satelliteSelectionRequestToken += 1;
renderPacketPanels(); renderPacketPanels();
loadTrackedSatelliteCatalog(); loadTrackedSatelliteCatalog();
loadReceiverDevices(); loadReceiverDevices();
@@ -1657,9 +1662,9 @@
} }
startTelemetryPolling(); startTelemetryPolling();
loadAgents(); loadAgents();
calculatePasses(); calculatePasses(selectedSatellite, _satelliteSelectionRequestToken);
loadTransmitters(selectedSatellite); loadTransmitters(selectedSatellite, _satelliteSelectionRequestToken);
fetchCurrentTelemetry(); fetchCurrentTelemetry(selectedSatellite, _satelliteSelectionRequestToken);
scheduleDashboardDataRetry(3500); scheduleDashboardDataRetry(3500);
if (!usedShared) { if (!usedShared) {
getLocation(); getLocation();
@@ -1894,10 +1899,10 @@
} }
} }
async function calculatePasses() { async function calculatePasses(requestedSatellite = selectedSatellite, selectionToken = _satelliteSelectionRequestToken) {
const lat = parseFloat(document.getElementById('obsLat').value); const lat = parseFloat(document.getElementById('obsLat').value);
const lon = parseFloat(document.getElementById('obsLon').value); const lon = parseFloat(document.getElementById('obsLon').value);
const requestTargets = getPassPredictionTargets(); const requestTargets = Number.isFinite(requestedSatellite) ? [requestedSatellite] : getPassPredictionTargets();
const requestKey = getActivePassRequestKey(requestTargets); const requestKey = getActivePassRequestKey(requestTargets);
const container = document.getElementById('passList'); const container = document.getElementById('passList');
const button = document.querySelector('.controls-bar .btn.primary'); const button = document.querySelector('.controls-bar .btn.primary');
@@ -1963,6 +1968,9 @@
if (data.status === 'success') { if (data.status === 'success') {
const resolvedPasses = Array.isArray(data.passes) ? data.passes : []; const resolvedPasses = Array.isArray(data.passes) ? data.passes : [];
cachePredictedPassBatch(resolvedPasses, requestTargets); cachePredictedPassBatch(resolvedPasses, requestTargets);
if (selectionToken !== _satelliteSelectionRequestToken || requestedSatellite !== selectedSatellite) {
return;
}
try { try {
applySelectedSatellitePasses(); applySelectedSatellitePasses();
@@ -1980,7 +1988,7 @@
document.getElementById('trackingDot').style.background = 'var(--accent-green)'; document.getElementById('trackingDot').style.background = 'var(--accent-green)';
_dashboardRetryAttempts = 0; _dashboardRetryAttempts = 0;
} else { } else {
if (applySelectedSatellitePasses()) { if (selectionToken === _satelliteSelectionRequestToken && requestedSatellite === selectedSatellite && applySelectedSatellitePasses()) {
document.getElementById('trackingStatus').textContent = 'TRACKING'; document.getElementById('trackingStatus').textContent = 'TRACKING';
document.getElementById('trackingDot').style.background = 'var(--accent-green)'; document.getElementById('trackingDot').style.background = 'var(--accent-green)';
} else { } else {
@@ -2008,7 +2016,7 @@
return; return;
} }
console.error('Pass calculation error:', err); console.error('Pass calculation error:', err);
if (applySelectedSatellitePasses()) { if (selectionToken === _satelliteSelectionRequestToken && requestedSatellite === selectedSatellite && applySelectedSatellitePasses()) {
document.getElementById('trackingStatus').textContent = 'TRACKING'; document.getElementById('trackingStatus').textContent = 'TRACKING';
document.getElementById('trackingDot').style.background = 'var(--accent-green)'; document.getElementById('trackingDot').style.background = 'var(--accent-green)';
} else { } else {
@@ -2468,7 +2476,7 @@
} }
} }
async function loadTransmitters(noradId) { async function loadTransmitters(noradId, selectionToken = _satelliteSelectionRequestToken) {
const container = document.getElementById('transmittersList'); const container = document.getElementById('transmittersList');
const countEl = document.getElementById('txCount'); const countEl = document.getElementById('txCount');
if (!container) return; if (!container) return;
@@ -2495,12 +2503,14 @@
? data.transmitters ? data.transmitters
: (BUILTIN_TX_FALLBACK[noradId] || []); : (BUILTIN_TX_FALLBACK[noradId] || []);
cacheTransmitters(noradId, txList); cacheTransmitters(noradId, txList);
if (selectionToken !== _satelliteSelectionRequestToken || noradId !== selectedSatellite) return;
renderTransmitters(txList); renderTransmitters(txList);
updateMissionDrawerInfo(); updateMissionDrawerInfo();
} catch (e) { } catch (e) {
if (requestId !== _txRequestId) return; if (requestId !== _txRequestId) return;
const cached = getCachedTransmitters(noradId); const cached = getCachedTransmitters(noradId);
if (cached?.transmitters?.length) { if (cached?.transmitters?.length) {
if (selectionToken !== _satelliteSelectionRequestToken || noradId !== selectedSatellite) return;
renderTransmitters(cached.transmitters); renderTransmitters(cached.transmitters);
updateMissionDrawerInfo(); updateMissionDrawerInfo();
return; return;
@@ -2508,6 +2518,7 @@
const fallback = BUILTIN_TX_FALLBACK[noradId] || []; const fallback = BUILTIN_TX_FALLBACK[noradId] || [];
if (fallback.length) { if (fallback.length) {
cacheTransmitters(noradId, fallback); cacheTransmitters(noradId, fallback);
if (selectionToken !== _satelliteSelectionRequestToken || noradId !== selectedSatellite) return;
renderTransmitters(fallback); renderTransmitters(fallback);
updateMissionDrawerInfo(); updateMissionDrawerInfo();
return; return;