gerard2p/koaton-cli

View on GitHub
src/support/CheckBundles.js

Summary

Maintainability
B
4 hrs
Test Coverage
import spin from '../spinner';
import { livereload } from '../utils/livereload';
import mkdir from '../utils/mkdir';
import BundleItem from './BundleItem';
import { watch as Watch } from 'chokidar';
import { resolve } from 'path';
import hasfile from '../utils/hasfile';
import { buildCSS, buildJS } from '../functions/builder';

let allBundles = {};
let hashes = {};
const spinner = spin();
function reloadFiles (bundle, files) {
    for (const file of files) {
        livereload.reload(`/${bundle.kind}/${file}`);
        // notifier('Koaton', `Reloading /${bundle.kind}/${file}`);
    }
}
async function onChange (bundle, file) {
    let filepath = resolve(file);
    let newhash = await hasfile(file);
    if (newhash !== hashes[filepath]) {
        reloadFiles(bundle, await bundle.build(bundle.kind === '.css' ? buildCSS : buildJS));
        hashes[filepath] = newhash;
    }
}
async function makehashes (files) {
    for (const file of files) {
        hashes[resolve(file)] = await hasfile(file);
    }
}
async function DetectChanges (changed) {
    const newconf = requireNoCache(ProyPath('config', 'bundles.js')).default;
    for (const bundle of Object.keys(newconf)) {
        let mustrebuild = false;
        if (allBundles[bundle]) {
            let current = allBundles[bundle].content;
            let incoming = newconf[bundle];
            let added = incoming.filter(o => { return current.indexOf(o) === -1; });
            let removed = current.filter(o => { return incoming.indexOf(o) === -1; });
            for (const add of added) {
                mustrebuild = true;
                // allBundles[bundle].add(add);
                hashes[resolve(add)] = await hasfile(add);
            }
            for (const remove of removed) {
                mustrebuild = true;
                // allBundles[bundle].remove(remove);
                delete hashes[resolve(remove)];
            }
            allBundles[bundle].clear();
            incoming.forEach(allBundles[bundle].add);
        } else {
            mustrebuild = true;
            allBundles[bundle] = new BundleItem(bundle, newconf[bundle], true);
            allBundles[bundle].watch(onChange.bind(null, allBundles[bundle]));
            scfg.bundles.add(bundle, []);
        }
        allBundles[bundle].isUpdating = true;
        if (mustrebuild) {
            reloadFiles(allBundles[bundle], await allBundles[bundle].build(allBundles[bundle].kind === '.css' ? buildCSS : buildJS));
        }
    }
    for (const bundle in allBundles) {
        if (!allBundles[bundle].isUpdating) {
            allBundles[bundle].watcher.close();
            delete allBundles[bundle];
            scfg.bundles.remove(bundle);
        } else {
            allBundles[bundle].isUpdating = false;
        }
    }
}
function logger (msg) {
    spinner.update(msg.replace(/\n|\t/igm, ''));
}
const bWatcher = new Watch(ProyPath('config', 'bundles.js'), {
    persistent: true,
    ignoreInitial: true,
    alwaysStat: false,
    awaitWriteFinish: {
        stabilityThreshold: 300,
        pollInterval: 100
    }
});
bWatcher.on('change', DetectChanges);
async function checkbundles () {
    spinner.start(50, 'Building Bundles'.green, undefined, process.stdout.columns);
    await mkdir(ProyPath('public', 'css'), null);
    await mkdir(ProyPath('public', 'js'), null);
    for (const bundle of configuration.bundles) {
        let b = allBundles[bundle.file] = new BundleItem(bundle.file, bundle.content, true);
        await b.build(bundle.kind === '.css' ? buildCSS : buildJS, logger);
        b.watch(onChange.bind(null, b));
        makehashes(b.sources);
    }
    spinner.end(`   ${__ok.green} Bundles Built`);
    return true;
}

export default checkbundles;