/** * ApiRequest class implementation. * * @summary api-request * @since 1.0.0 * @version 3.0.0 * @author Arian Khosravi <arian.khosravi@aofl.com> */ import FormatterManager from '../formatter-manager'; import {CacheManager, cacheTypeEnumerate} from '@aofl/cache-manager'; /** * @memberof module:@aofl/api-request */ class ApiRequest { /** * @type {String} * @static * @readonly */ static get DEFAULT_CACHE_NAMESPACE() { return 'ApiRequest'; } /** * Creates an instance of ApiRequest. */ constructor() { this.formatterManager = new FormatterManager(); this.cacheManagers = {}; this.addCacheManager(ApiRequest.DEFAULT_CACHE_NAMESPACE); } /** * addformatter() adds a new format to formatter's list. * * @param {String} format name for the formatter * @param {FormatterManager} formatter formatter object */ addFormatter(format, formatter) { this.formatterManager.addFormatter(format, formatter); } /** * * @param {String} namespace * @param {Number} expire */ addCacheManager(namespace, expire) { if (Object.hasOwnProperty.call(this.cacheManagers, namespace)) { throw new Error(`ApiRequest: Cache namespace ${namespace} already exists`); } this.cacheManagers[namespace] = new CacheManager(namespace, cacheTypeEnumerate.MEMORY, expire); } /** * Returns an existing cacheManager if it exists or creates a new one and assigns it to the * namespace. * * @param {String} namespace cache namespace * @param {Number} expire * @return {CacheManager} */ getCacheManager(namespace, expire) { try { if (typeof namespace === 'undefined') { namespace = ApiRequest.DEFAULT_CACHE_NAMESPACE; } else { this.addCacheManager(namespace, expire); } } catch (e) {} return this.cacheManagers[namespace]; } /** * Update a cache managers expire time * @param {String} namespace * @param {Number} expire */ updateCacheInterval(namespace, expire) { const manager = this.getCacheManager(namespace, expire); manager.expire = expire; } /** * * * @param {String} namespace */ purgeCache(namespace) { if (typeof namespace === 'undefined') { // purge all for (const key in this.cacheManagers) { /* istanbul ignore next */ if (!Object.hasOwnProperty.call(this.cacheManagers, key)) continue; this.cacheManagers[key].clear(); } } else { this.cacheManagers[namespace].clear(); } } /** * Makes a network call using fetch API. * * @param {String} url request url * @param {*} payload data * @param {String} format formatter name * @param {Boolean} fromCache fetch new data or return cached * @param {String} namespace cache manager namespace * @return {Promise} */ request(url, payload, format, fromCache = true, namespace = 'default', expire) { const formatter = this.formatterManager.getFormatter(format); const cacheKey = url + JSON.stringify(payload); const cacheManager = this.getCacheManager(namespace, expire); const cacheResponse = cacheManager.getItem(cacheKey); if (fromCache && cacheResponse) { return cacheResponse; } const requestPromise = fetch(url, formatter.pack(payload)) .then(formatter.unpack); cacheManager.setItem(cacheKey, requestPromise); return requestPromise; } /** * Clears cached data by namespace. * * @param {String} namespace cache namespace */ clearCache(namespace) { const cacheManager = this.getCacheManager(namespace); cacheManager.clear(); } } export default ApiRequest;