RSS Git Download  Clone
Raw Blame History
const resolveDependencies = (options) => {

    if (Array.isArray(options)) {
        options = {
            modules: options
        }
    }

    let {
        modules,
        recursive,
        debug
    } = options;

    recursive = recursive || [];
    if (debug) {
        dconsole = console;
    } else {
        dconsole = {
            info: () => {
            },
        }
    }

    let resovledModules = [];
    let lastWrongModule;
    let iteration = 0;
    dconsole.info(`Modules: ${modules.length}`);

    const ensureWants = () => {
        iteration++;
        dconsole.info();
        dconsole.info(`Iteration: ${iteration}`)
        let totalOk = true;

        for (let index = 0; index < modules.length; index++) {
            const loadedModule = modules[index];
            dconsole.info();
            dconsole.info(`Module: ${loadedModule.name}`);

            if (recursive.includes(loadedModule.name)) {
                if (!resovledModules.includes(loadedModule)) {
                    dconsole.info(`Adding to the recursived list`);
                    resovledModules.push(loadedModule);
                }
            }
            if (resovledModules.includes(loadedModule)) {
                dconsole.info(`Already got it`);
                continue;
            }
            let ok = true
            loadedModule.wants.forEach((want) => {
                let found = false;
                resovledModules.forEach((resultModule) => {
                    if (resultModule.name === want) {
                        found = true;
                    }
                })
                if (!found) {
                    ok = false;
                    totalOk = false;
                }
            })
            if (ok) {
                dconsole.info(`Found!`);
                resovledModules.push(loadedModule);
            } else {
                lastWrongModule = {
                    name: loadedModule.name,
                    wants: loadedModule.wants
                }
            }
        }

        return totalOk;
    }

    let checkCircular;
    while (!ensureWants()) {
        if (checkCircular === undefined) {
            checkCircular = resovledModules.length;
            continue;
        }

        if (checkCircular === resovledModules.length) {
            const print = (datas) => {
                return JSON.stringify(datas.map((data) => {
                    return {
                        name: data.name,
                        wants: data.wants
                    }
                }), null, 2)
            }
            dconsole.info(`
Loaded factories
`, print(modules))

            dconsole.info(`
Wanted factories in order
`, print(resovledModules));
            dconsole.info(`
Last wrong factory
`, lastWrongModule);
            dconsole.info(`

`)
            throw Error('circular loading factory');
        }
        checkCircular = resovledModules.length;
    }
    return resovledModules;
}

module.exports.resolveDependencies = resolveDependencies;