1'use strict' 2 3const { LRUCache } = require('lru-cache') 4const dns = require('dns') 5 6// this is a factory so that each request can have its own opts (i.e. ttl) 7// while still sharing the cache across all requests 8const cache = new LRUCache({ max: 50 }) 9 10const getOptions = ({ 11 family = 0, 12 hints = dns.ADDRCONFIG, 13 all = false, 14 verbatim = undefined, 15 ttl = 5 * 60 * 1000, 16 lookup = dns.lookup, 17}) => ({ 18 // hints and lookup are returned since both are top level properties to (net|tls).connect 19 hints, 20 lookup: (hostname, ...args) => { 21 const callback = args.pop() // callback is always last arg 22 const lookupOptions = args[0] ?? {} 23 24 const options = { 25 family, 26 hints, 27 all, 28 verbatim, 29 ...(typeof lookupOptions === 'number' ? { family: lookupOptions } : lookupOptions), 30 } 31 32 const key = JSON.stringify({ hostname, ...options }) 33 34 if (cache.has(key)) { 35 const cached = cache.get(key) 36 return process.nextTick(callback, null, ...cached) 37 } 38 39 lookup(hostname, options, (err, ...result) => { 40 if (err) { 41 return callback(err) 42 } 43 44 cache.set(key, result, { ttl }) 45 return callback(null, ...result) 46 }) 47 }, 48}) 49 50module.exports = { 51 cache, 52 getOptions, 53} 54