Source: widget/Infrastructure.js

(function() {
    let _INTEGRATED = false;

    /**
     * Widget infrastructure helpers.
     */
    Help4.widget.Infrastructure = class {
        /**
         * see {@link Help4.widget.Widget#start} and {@link Help4.widget.Infrastructure.integrate}
         * @memberof Help4.widget.Infrastructure
         * @type {?Object}
         */
        static INTEGRATION = null;

        /**
         * starts the integration within SAP Companion 4 infrastructure
         * @returns {Promise<void>}
         */
        static async integrate() {
            const {Infrastructure} = Help4.widget;

            if (_INTEGRATED) return;  // do not integrate twice
            _INTEGRATED = true;

            // create widgets
            const INTEGRATION = Infrastructure.INTEGRATION = {};
            const {widget} = Help4;
            for (const [name, namespace] of Object.entries(widget)) {
                if (namespace.Widget) {
                    INTEGRATION[name] = 1;
                    widget.create(name);
                }
            }

            // wait for widget creation
            await new Help4.Promise(resolve => {
                const check = () => {
                    // wait for all to-be-integrated widgets to be initialized
                    for (const name of Object.keys(INTEGRATION)) {
                        const instance = widget.getInstance(name);
                        if (instance?.isStarted()) delete INTEGRATION[name];
                    }

                    if (Object.keys(INTEGRATION).length) {
                        // some not loaded; wait
                        return void setTimeout(check, 10);
                    } else {
                        // all completed
                        Infrastructure.INTEGRATION = null;
                        resolve();
                    }
                }
                check();
            });
        }

        /**
         * terminates the integration within SAP Companion 4 infrastructure
         * @returns {Promise<void>}
         */
        static async terminate() {
            const promises = [];
            const {INSTANCES} = Help4.widget;
            for (/** @type {Help4.widget.Widget} */ const instance of INSTANCES) {
                promises.push(instance.destroy());
            }
            await Help4.Promise.all(promises);

            _INTEGRATED = false;
        }

        /**
         * autostart widget instances based on their configured autostart dependencies
         * @returns {Promise<void>}
         */
        static async autostart() {
            const {widget} = Help4;

            for (const instance of Help4.widget.INSTANCES) {
                if (!instance.isStarted()) {
                    const {autostart} = instance.getDescriptor();
                    const allStarted = autostart?.length && autostart.every(name => widget.getInstance(name)?.isStarted());
                    if (allStarted) await instance.start();
                }
            }
        }
    }
})();