"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const got = require("got");
const pLimit = require("p-limit");
const uuid = require("uuid");
function default_1(initOpts) {
    const remotePrefix = initOpts.remotePrefix;
    const limitedFetch = fetch.bind(null, pLimit(initOpts.concurrency || 100));
    return new Promise((resolve, reject) => {
        resolve({
            close: () => __awaiter(this, void 0, void 0, function* () { return; }),
            importPackage: (from, to, opts) => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/importPackage`, {
                    from,
                    opts,
                    to,
                });
            }),
            prune: () => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/prune`, {});
            }),
            requestPackage: requestPackage.bind(null, remotePrefix, limitedFetch),
            saveState: () => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/saveState`, {});
            }),
            stop: () => limitedFetch(`${remotePrefix}/stop`, {}),
            updateConnections: (prefix, opts) => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/updateConnections`, {
                    opts,
                    prefix,
                });
            }),
            upload: (builtPkgLocation, opts) => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/upload`, {
                    builtPkgLocation,
                    opts,
                });
            }),
        });
    });
}
exports.default = default_1;
function fetch(limit, url, body) {
    return limit(() => __awaiter(this, void 0, void 0, function* () {
        const response = yield got(url, {
            body: JSON.stringify(body),
            headers: { 'Content-Type': 'application/json' },
            method: 'POST',
            retries: () => {
                return 100;
            },
        });
        if (!response.body) {
            return undefined;
        }
        return JSON.parse(response.body);
    }));
}
function requestPackage(remotePrefix, limitedFetch, // tslint:disable-line
    wantedDependency, options) {
    const msgId = uuid.v4();
    return limitedFetch(`${remotePrefix}/requestPackage`, {
        msgId,
        options,
        wantedDependency,
    })
        .then((packageResponseBody) => {
        const fetchingManifest = packageResponseBody['manifest'] // tslint:disable-line
            ? undefined
            : limitedFetch(`${remotePrefix}/manifestResponse`, {
                msgId,
            });
        if (options.skipFetch) {
            return {
                body: packageResponseBody,
                fetchingManifest,
            };
        }
        const fetchingFiles = limitedFetch(`${remotePrefix}/packageFilesResponse`, {
            msgId,
        });
        return {
            body: packageResponseBody,
            fetchingFiles,
            fetchingManifest,
            finishing: Promise.all([fetchingManifest, fetchingFiles]).then(() => undefined),
        };
    });
}
//# sourceMappingURL=connectStoreController.js.map