libflitter/app/AppUnit.js

/**
 * @module libflitter/app/AppUnit
 */

const Unit = require('../Unit')

/**
 * The app unit is the final unit in the stack, and makes the final call
 * to the Express HTTP server. As such, it is the innermost context which
 * the Flitter application can access. No other units after this will show
 * up to the Flitter components as being started.
 *
 * @extends module:libflitter/Unit~Unit
 */
class AppUnit extends Unit {
    /**
     * Defines the services required by this unit.
     * @returns {Array<string>}
     */
    static get services() {
        return [...super.services, 'output', 'configs', 'express']
    }

    /**
     * Defines the name of the service provided by this unit: 'http'
     * @returns {string} - 'http'
     */
    static get name() {
        return "http"
    }

    /**
     * Loads the unit. Launches the HTTP server.
     * @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app
     * @returns {Promise<void>}
     */
    async go(app){
        await this.serve_express(app)
    }

    /**
     * Launch an HTTP server from the underlying Express app on the port configured by the config value "server.port".
     * @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app to be served
     * @returns {Promise<any>}
     */
    serve_express(app){
        const port = this.configs.get('server.port')
        const server = this.express.server
        
        return new Promise(
            (resolve, reject) => {
                server.listen(port, (error) => {
                    if (error) reject(error)
                    
                    this.output.success(`Flitter running on port ${port}! Press ^C to exit cleanly.`, 0)

                    process.on('SIGTERM', async () => {
                        await server.close()
                        return resolve()
                    })

                    process.on('SIGINT', async () => {
                        await server.close()
                        return resolve()
                    })
                })
            }
        )
    }

    /**
     * Clean up the unit resources. Closes the Express HTTP(S) server.
     * @param {module:libflitter/app/FlitterApp~FlitterApp} app
     * @returns {Promise<void>}
     */
    async cleanup(app) {
        this.express.server.close()
    }
}

module.exports = AppUnit