const { fetchJSON } = require("./services/http-helpers"); // Atlas Probe Cache (for Lia's Atlas Paradise). Exposed as a mutable state // object (not a bare reassigned export) so every requirer always sees the // current value after fetchAllAtlasProbes() resolves -- a plain // `module.exports = { atlasProbeCache }` would only capture the value (null) // at require time, since CommonJS destructuring doesn't track reassignment. const atlasState = { cache: null, fetching: false, }; function fetchAllAtlasProbes() { if (atlasState.fetching) return Promise.resolve(); atlasState.fetching = true; console.log("[ATLAS] Fetching all Atlas probes..."); return new Promise(function(resolve) { var allAsns = new Set(); var byCountry = {}; var pageCount = 0; var maxPages = 40; function fetchPage(pageUrl) { if (pageCount >= maxPages) return finish(); pageCount++; fetchJSON(pageUrl).then(function(data) { if (!data || !data.results) return finish(); data.results.forEach(function(probe) { var asn4 = probe.asn_v4; var asn6 = probe.asn_v6; var cc = probe.country_code || "XX"; if (!byCountry[cc]) byCountry[cc] = { total: 0, connected: 0, asnSet: new Set() }; byCountry[cc].total++; if (probe.status && probe.status.id === 1) byCountry[cc].connected++; if (asn4) { allAsns.add(asn4); byCountry[cc].asnSet.add(asn4); } if (asn6) { allAsns.add(asn6); byCountry[cc].asnSet.add(asn6); } }); if (data.next) { fetchPage(data.next); } else { finish(); } }).catch(function() { finish(); }); } function finish() { var byCountryOut = {}; Object.keys(byCountry).forEach(function(cc) { var info = byCountry[cc]; byCountryOut[cc] = { total: info.total, connected: info.connected, asn_count: info.asnSet.size }; }); atlasState.cache = { total_probes: Object.keys(byCountry).reduce(function(s, cc) { return s + byCountry[cc].total; }, 0), total_connected: Object.keys(byCountry).reduce(function(s, cc) { return s + byCountry[cc].connected; }, 0), unique_asns_with_probes: allAsns.size, asns_with_probes: Array.from(allAsns).sort(function(a, b) { return a - b; }), by_country: byCountryOut, fetched_at: new Date().toISOString(), pages_fetched: pageCount, }; console.log("[ATLAS] Loaded " + allAsns.size + " unique ASNs with probes (" + pageCount + " pages)"); atlasState.fetching = false; resolve(); } fetchPage("https://atlas.ripe.net/api/v2/probes/?page_size=500&status=1&page=1&format=json"); }); } module.exports = { atlasState, fetchAllAtlasProbes };