/**
* @author Vivek Kumar <vivek.kumar26@live.com>
* @overview DNS Cache Memoized.
* @copyright Vivek Kumar 2018
* @license MIT
*/
import EventEmitter from 'events';
import createCacheStore from '../cache';
import { getAllDnsMethods, memoizeDnsMethods } from './memoize-dns';
/* eslint-disable class-methods-use-this */
/* eslint-disable arrow-parens */
/** Cached DNS Class - Override DNS Methods */
export class CachedDNS extends EventEmitter {
/**
* Creates an instance of CachedDNS.
* @param {number} [ttl] TTL value for cache items in minutes.
* @param {object} [config] Config / Options object.
* @param {number} [config.maxSize] Maximum number of items to be stored in cache.
* @memberof CachedDNS
*/
constructor(ttl, config) {
super();
/* Allow only one instance of CachedDNS class */
if (CachedDNS.$instance) {
throw new Error('CachedDNS Class already has an instance!');
}
CachedDNS.$instance = this;
this.methods = null;
/* Create Cache Store Object (Static) */
CachedDNS.cacheObj = createCacheStore(ttl, config);
/**
* Flush Complete Event Listener.
* @listens CacheStore#flush-complete
*/
CachedDNS.cacheObj.on('flush-complete', (stats) => {
/**
* Flush Cache Event.
* @event CachedDNS#flush-cache
* @type {object}
* @property {boolean} status Indicates status.
* @property {number} nTimeouts Number of timeouts cleared.
* @property {number} nKeys Number of cache items cleared.
*/
this.emit('flush-cache', stats);
});
}
/**
* Override all DNS Methods.
* @returns {boolean}
* @memberof CachedDNS
*/
overrideMethods(options) {
const allDnsMethods = getAllDnsMethods();
if (!options) {
this.methods = allDnsMethods;
} else if (typeof options === 'string') {
if (allDnsMethods.includes(options)) {
this.methods = [options];
} else {
throw new Error(`Invalid DNS Method - '${options}'`);
}
} else if (Array.isArray(options)) {
if (options.every((m) => allDnsMethods.includes(m))) {
this.methods = options;
} else {
throw new Error('An invalid dns method was passed');
}
} else {
throw new TypeError('Expected a string or an array of strings');
}
memoizeDnsMethods(this.methods, CachedDNS.cacheObj);
return true;
}
/**
* Flushes the cache and clears all timers.
* Once flushing is complete, emits `flush-cache` event with stats object.
* @memberof CachedDNS
*/
flush() {
CachedDNS.cacheObj.flush = true;
CachedDNS.cacheObj.flushCache();
}
}
/**
* Function to create a new instance of CachedDNS class.
* @param {number} ttl TTL value for cache items in minutes.
* @param {object} config Config / Options object.
* @param {number} config.maxSize Maximum number of items to be stored in cache.
* @returns {object} Instance of CachedDNS class.
*/
const dnsCached = (ttl, config) => new CachedDNS(ttl, config);
export default dnsCached;