gluebert.bootstrap.js

import { ModuleLauncher } from './module/module.launcher';
import { DataObserver } from './data/data.observer';
import { DataManager } from './data/data.manager';
import { ElementBuilder } from './element/element.builder';
import { Polyfill } from './polyfills/polyfill.service';

const DEFAULT_OPTIONS = {
    elementReadyClass: `gb-ready`,
    elementSleepingClass: `gb-sleep`,
    elementLoadingClass: `gb-loading`,
};

/**
 * Class represents Gluebert
 */
class Gluebert {

    /**
     * @param {ModuleSignature[]} modules
     * @param {DataSignature[]} data
     * @param {object} options
     */
    constructor(modules, data = [], options = {}) {

        this._options = Object.assign(
            {},
            DEFAULT_OPTIONS,
            options,
        );

        this._modules = (modules instanceof Array) ? modules : null;
        this._elements = (this._modules) ? this._extractElements(modules) : null;
        this._data = (data instanceof Array) ? data : null;
        this._schemaValidator = null;
        this._templateEngine = null;
        this._polyfillService = new Polyfill();
    }

    start() {
        this._polyfillService
            .fill()
            .then(() => {
                this._init();
            });
        return this;
    }

    /**
     * start binding methods and properties
     * @private
     */
    _init() {

        this.elementBuilder = new ElementBuilder(
            this._elements,
            this._templateEngine,
            this._schemaValidator,
            this._options,
        );

        this.dataObserver = new DataObserver();

        this.dataManager = new DataManager(this.dataObserver, this._data);

        this.moduleLauncher = new ModuleLauncher(
            this._modules,
            this.dataObserver,
            this.elementBuilder,
        );
    }

    /**
     * extract elements list from modules
     * @param {ModuleSignature[]} modules
     * @return {ElementSignature[]}
     * @private
     */
    _extractElements(modules) {
        return modules.reduce((a, b) => {
            let elements = b.getElementSignatures();
            if(elements.size) {
                a.push(...elements);
            }
            return a;
        }, []);
    }

    /**
     * set JSON Schema validator Gluebert uses for elements
     * @param schemaValidator
     * @return {Gluebert}
     */
    setSchemaValidator(schemaValidator) {
        if(schemaValidator === 'function') {
            this._schemaValidator = schemaValidator;
        }

        return this;
    }

    /**
     * set template engine
     * @param templateEngine
     * @return {Gluebert}
     */
    setTemplateEngine(templateEngine) {
        if(typeof templateEngine === 'object') {
            this._templateEngine = templateEngine;
        }

        return this;
    }
}

export {
    Gluebert,
};