UNPKG

@multiformats/dns

Version:

Resolve DNS queries with browser fallback

73 lines 2.68 kB
import { CustomProgressEvent } from 'progress-events'; import { defaultResolver } from './resolvers/default.js'; import { cache } from './utils/cache.js'; import { getTypes } from './utils/get-types.js'; const DEFAULT_ANSWER_CACHE_SIZE = 1000; export class DNS { resolvers; cache; constructor(init) { this.resolvers = {}; this.cache = cache(init.cacheSize ?? DEFAULT_ANSWER_CACHE_SIZE); Object.entries(init.resolvers ?? {}).forEach(([tld, resolver]) => { if (!Array.isArray(resolver)) { resolver = [resolver]; } // convert `com` -> `com.` if (!tld.endsWith('.')) { tld = `${tld}.`; } this.resolvers[tld] = resolver; }); // configure default resolver if none specified if (this.resolvers['.'] == null) { this.resolvers['.'] = defaultResolver(); } } /** * Queries DNS resolvers for the passed record types for the passed domain. * * If cached records exist for all desired types they will be returned * instead. * * Any new responses will be added to the cache for subsequent requests. */ async query(domain, options = {}) { const types = getTypes(options.types); const cached = options.cached !== false ? this.cache.get(domain, types) : undefined; if (cached != null) { options.onProgress?.(new CustomProgressEvent('dns:cache', { detail: cached })); return cached; } const tld = `${domain.split('.').pop()}.`; const resolvers = (this.resolvers[tld] ?? this.resolvers['.']).sort(() => { return (Math.random() > 0.5) ? -1 : 1; }); const errors = []; for (const resolver of resolvers) { // skip further resolutions if the user aborted the signal if (options.signal?.aborted === true) { break; } try { const result = await resolver(domain, { ...options, types }); for (const answer of result.Answer) { this.cache.add(domain, answer); } return result; } catch (err) { errors.push(err); options.onProgress?.(new CustomProgressEvent('dns:error', { detail: err })); } } if (errors.length === 1) { throw errors[0]; } throw new AggregateError(errors, `DNS lookup of ${domain} ${types} failed`); } } //# sourceMappingURL=dns.js.map