Source: client.js

import CircuitBreaker from "opossum";
import Fetcher from "./fetcher";
import { getBreakerIndex } from "./utils";
/**
 * Constructs a ResilientClient.
 *
 * @class Client
 * @param {CircuitBreaker.Options} circuitBreakerOptions Options for the circuit breaker
 * @param {AxiosRequestConfig} requestOptions Options for the {@link Fetcher}
 */
class Client {
    constructor(circuitBreakerOptions, requestOptions) {
        this._circuits = new Map();
        this._cbOptions = circuitBreakerOptions;
        this._fetcher = new Fetcher(requestOptions);
    }
    /**
     * Perform a HTTP request that might fails
     *
     * @param {AxiosRequestConfig} fetchConfig Options for the {@link Fetcher}
     * @return {Promise<AxiosResponse>} Promise resolves with the HTTP response
     * on success or is rejected on failure of the action. Use isBreakerError()
     * to determine if a rejection was a result of the circuit breaker or the
     * HTTP call.
     */
    request(fetchConfig) {
        const { method, url } = fetchConfig;
        if (method && url) {
            let breaker;
            const abortController = new AbortController();
            const circuitBreakerOptions = Object.assign({ abortController }, this._cbOptions);
            const circuitIndexObject = {
                requestMethod: method,
                requestURL: url,
            };
            const circuitIndexString = getBreakerIndex(circuitIndexObject);
            if (this._circuits.has(circuitIndexString)) {
                breaker = this._circuits.get(circuitIndexString);
            }
            else {
                breaker = new CircuitBreaker(this._fetcher.exec, circuitBreakerOptions);
                this._circuits.set(circuitIndexString, breaker);
            }
            return breaker.fire(circuitBreakerOptions.abortController.signal, fetchConfig);
        }
        else {
            throw new Error("Method and URL are required in request config");
        }
    }
    /**
     * Returns true if the provided error was generated by an circuit breaker. It will be false
     * if the error came from the action itself.
     *
     * @param {Error} error The Error to check
     * @returns {Boolean} true if the error was generated by an circuit breaker
     */
    static isBreakerError(error) {
        return CircuitBreaker.isOurError(error);
    }
    /**
     * Get an specific circuit breaker.
     * Helpful when you need to get stats from a circuit breaker.
     *
     * @param {BreakerIndexObject} indexObject IndexObject contains the URL and method of the request
     * associated with a circuit breaker. Request and URL together are used as index for the circuit breaker.
     * They can be formatted into an string index using {@link BreakerIndexObject}
     * @returns {CircuitBreaker} Circuit breaker
     */
    getCircuitBreaker(indexObject) {
        const index = getBreakerIndex(indexObject);
        const breaker = this._circuits.get(index);
        if (breaker) {
            return breaker;
        }
        else {
            throw new Error(`There is no circuit breaker with index ${index}`);
        }
    }
}
export default Client;