import {query} from 'dns-query'; function get_prefered_server() { try { const servers = JSON.parse(localStorage.getItem('dns-servers')); if (servers && servers.length > 0) { return servers; } } catch (e) { console.error(e); } const request = new XMLHttpRequest(); request.open('GET', '/local/dns', false); request.send(null); if (request.status === 200) { try { const servers = JSON.parse(request.responseText); if (servers && servers.length > 0) { return servers; } } catch (e) { console.error(e); } } return ['1.1.1.1', '8.8.8.8']; } class FallBackResolver { constructor() { this._servers = get_prefered_server(); this._cache = JSON.parse(localStorage.getItem('dns-cache')) || {}; } async query(domain, type) { const key = domain + ':' + type; if (key in this._cache && this._cache[key].time > Date.now() - 1000 * 60 * 60) { const age_seconds = Math.ceil(Date.now() / 1000 - this._cache[key].time / 1000); return [this._cache[key].data]; } const result = await query( {question: {type: type, name: domain}}, { endpoints: this._servers, } ) if (result.answers.length === 0) throw new Error('No answer'); const first = result.answers[0]; this._cache[key] = {time: Date.now(), ...first}; // TODO hadle multiple answers localStorage.setItem('dns-cache', JSON.stringify(this._cache)); return [first.data]; } } export default FallBackResolver;