"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CachedDns = void 0;
exports.dnsLookup = dnsLookup;
const dns = require("dns");
// A drop-in alternative to dns.lookup, but where results are briefly cached to avoid completely
// unnecessary lookups, while remaining fairly reactive to actual host file changes etc.
class CachedDns {
    constructor(cacheDurationMs) {
        this.cacheDurationMs = cacheDurationMs;
        this.cache = new Map();
        this.lookup = (...args) => {
            const [hostname, options] = args.slice(0, -1);
            const cb = args[args.length - 1];
            const key = this.cacheKey(hostname, options);
            const cachedResult = this.cache.get(key);
            if (cachedResult) {
                setImmediate(() => cb(null, ...cachedResult));
            }
            else {
                dns.lookup(hostname, options ?? {}, (err, ...cbArgs) => {
                    if (!err) {
                        this.cache.set(key, cbArgs);
                        // Always refresh Xms after initially inserted - no LRU or similar
                        setTimeout(() => this.cache.delete(key), this.cacheDurationMs).unref();
                    }
                    return cb(err, ...cbArgs);
                });
            }
        };
    }
    cacheKey(hostname, options) {
        return `${hostname}-${options?.all}-${options?.family}-${options?.hints}-${options?.verbatim}`;
    }
}
exports.CachedDns = CachedDns;
function dnsLookup(lookupFn, hostname) {
    return new Promise((resolve, reject) => {
        lookupFn(hostname, (err, address) => {
            if (err)
                reject(err);
            else
                resolve(address);
        });
    });
}
//# sourceMappingURL=dns.js.map