npm package: @nexgin/totaljsapplication
Description: TotalJS Application Components
Author: Colton McInroy
Latest version: 0.0.66

<div align="center" style="text-align: center;">
  <h1 style="border-bottom: none;">TotalJS Application</h1>

  <p>Building Scalable Applications with TotalJS Flow</p>
  <img src="images/ApplicationComponent.png" alt="Application Component" width="163" />
  <img src="images/ModuleComponent.png" alt="Module Component" width="163" />
</div>

<h1>UNDER CONSTRUCTION: DO NOT USE</h1>
<hr />

[//]: # ([![Follow me][follow-me-badge]][follow-me-url])

[![Version][version-badge]][version-url]
[![Node version][node-version-badge]][node-version-url]
[![MIT License][mit-license-badge]][mit-license-url]

[![Downloads][downloads-badge]][downloads-url]
[![Total downloads][total-downloads-badge]][downloads-url]
[![Packagephobia][packagephobia-badge]][packagephobia-url]
[![Bundlephobia][bundlephobia-badge]][bundlephobia-url]

[//]: # ([![Dependency Status][daviddm-badge]][daviddm-url])

[//]: # ([![codecov][codecov-badge]][codecov-url])

[//]: # ([![Coverage Status][coveralls-badge]][coveralls-url])

[//]: # ([![codebeat badge][codebeat-badge]][codebeat-url])

[//]: # ([![Codacy Badge][codacy-badge]][codacy-url])

[//]: # ([![Code of Conduct][coc-badge]][coc-url])


## Table of contents <!-- omit in toc -->

- [Description](#description)
- [Dependencies](#dependencies)
- [Application Configuration](#application-configuration)
- [Application Bootstrapping](#application-bootstrapping)
- [Module Configuration](#module-configuration)
- [Module Bootstrapping](#module-bootstrapping)
- [Application Flow Architecture](#application-flow-architecture)
- [Pre-requisites](#pre-requisites)
- [Setup](#setup)
  - [Install](#install)
    - [Install Application](#install-application)
    - [Install Module](#install-module)
- [License](#license)

## Description
This project provides a set of components to help build applications using [TotalJS Flow][totaljs-flow-url].
The two main components are the [Application][application-component-url] and the [Module][module-component-url].
The Application is responsible for processing requests and managing the modules. The Module is responsible for
handling all the operational logic.<br /><br />
The TotalJS Flow project is a great tool for developing applications using flow based programming.
When building larger applications where inter-module communication, multiphase processing, and
scaling need to be taken into account it can be difficult to manage. This project provides a
set of components to facilitate the building of larger applications using TotalJS Flow.<br /><br />
Both the Application and the Module need to communicate with a redis server. Redis is used
as the backend for how Application and Module instances communicate with each other.<br /><br />
The Application component needs to communicate with a MongoDB server. The MongoDB server
is primarily used to store details about the modules and their status. This is used so that
the Application instances can be scaled out horizontally and keep in sync when it comes to
processing.<br /><br />


## Dependencies
- TotalJS Flow
- Redis Server
- RethinkDB Server


## Application Configuration
- Application Name (Required: String)
- Processing Mode (Required: String)
  - "Everything" (all) = Both input and API requests are processed
  - "Input" (input) = Only input requests are processed
  - "API" (api) = Only API requests are processed 
- Redis Connection (Required: String)
- RethinkDB Connection (Required: String)

## Application Bootstrapping
- Application does sanity checks on the configuration<br />
  - Check connection to MongoDB and Redis<br />
- Then application executes the "init" phase.<br />
  - Initialize the Application Worker<br />
  - Initialize the Module Manager<br />
  - Create a new FlowMessage (with config as data) then send it to the "init" output and store message data on 'end' as Application Data (AppData)<br />
- Then application executes the "boot" phase.<br />
  - Boot the Application Worker<br />
  - Boot the Module Manager<br />
  - Create a new FlowMessage then send it to the "boot" output with AppData and update message data on 'end' as AppData<br />
- Then application executes the "start" phase.<br />
  - Start the Application Worker<br />
  - Start the Module Manager<br />
  - Create a new FlowMessage then send it to the "start" output with AppData and update message data on 'end' as AppData<br />
- Then application executes the "ready" phase.<br />
  - Ready the Application Worker<br />
  - Ready the Module Manager<br />
  - Create a new FlowMessage then send it to the "ready" output with AppData and update message data on 'end' as AppData<br />
  - Start the status monitor which sends status to UI at interval<br />
- The application is now ready to process requests.<br />


## Module Configuration
- Label (Required: String)
- Name (Required: String)
- Application (Required: String)
- Mode (Required: String)
  - "Everything" (all) = Both input and API requests are processed
  - "Input" (input) = Only input requests are processed
  - "API" (api) = Only API requests are processed
- Redis Connection (Required: String)

## Module Bootstrapping
- Module does sanity checks on the configuration<br />
  - Check connection to Redis<br />
- Then module connects to the application and registers itself.<br />
  - Module sends a AppRegisterMessage to the application informing it of its existence.<br />
  - Application responds with a AppRegisterResponse.<br />
- If AppRegisterResponse.success is true, then the module is registered.<br />
  - Module executes the "init" phase.<br />
    - Initialize the Module Worker<br />
    - Create a new FlowMessage (with config as data) then send it to the "init" output and store message data on 'end' as Module Data (ModData)<br />
  - Module executes the "boot" phase.<br />
    - Boot the Module Worker<br />
    - Create a new FlowMessage then send it to the "boot" output with ModData and update message data on 'end' as ModData<br />
  - Module executes the "start" phase.<br />
    - Start the Module Worker<br />
    - Create a new FlowMessage then send it to the "start" output with ModData and update message data on 'end' as ModData<br />
  - Module executes the "ready" phase.<br />
    - Ready the Module Worker<br />
    - Create a new FlowMessage then send it to the "ready" output with ModData and update message data on 'end' as ModData<br />
    - Start the status monitor which sends status to UI at interval<br />
    - Start heartbeat monitor which sends heartbeat to application at interval<br />
- If AppRegisterResponse.success is false, then the module is not registered.<br />
  - Module is disabled.<br />


## Application Flow Architecture
- Application Input (Input -> Phases -> Output)
  - Application Input is the entry point for the application which is the input labeled "input".<br />
  - Application Input is then sent to the "phases" output with the result being an array of strings used for that inputs processing phases.<br />
  - Application Input metadata is sent to each module requesting its involvement (phases and priority).<br />
  - Application Input is processed by each module involved according to priority with the results becoming the updated Application Input.<br />
  - Resulting Application Input is sent to "output" output for final processing.<br />
- Application Message (Message -> Application -> Response)
  - Application Message is the message that is sent to the application from a module.<br />
  - Application Messages are sent to the application via the BullMQ job queue system.<br />
  - AppRegisterMessage is sent to the application to register a module.<br />
  - AppUnregisterMessage is sent to the application to unregister a module.<br />
  - AppHeartbeatMessage is sent to the application to inform it that a module is still alive.<br />
  - AppAPIMessage is sent to the application to execute an API call (Handled by "api" output. When the message ends the data is sent back as the result).<br />
  - AppModuleMessage is sent to the application to execute a module API call.<br />
  - Application Messages are sent to the "api" output with the result being sent back to the module as an AppMessageResponse.<br />
- Module Message (Module <-> Application <-> Module)
  - Module Message is the message that is sent to a module from the another module through the Application.<br />
  - Module Messages are sent to the application via the BullMQ job queue system.<br />
  - The application sends the message to the appropriate module for processing and the result is sent back to the requesting module.<br />

## Pre-requisites

- [Node.js][nodejs-url] >= 8.16.0
- [NPM][npm-url] >= 6.4.1 ([NPM][npm-url] comes with [Node.js][nodejs-url] so there is no need to install separately.)

## Setup

### Install

#### Install Application
- Create a new TotalJS Flow.
- Create a new component and containing the contents of [Application Component][application-component-url].
- Add the Application component under the "Application" group to the Flow.
- Attach desired input and outputs to the Application component.
- Configure Application component.

#### Install Module
- Create a new TotalJS Flow.
- Create a new component and containing the contents of [Module Component][module-component-url].
- Add the Module component under the "Module" group to the Flow.
- Attach desired input and outputs to the Module component.
- Configure Module component.

## Messages

### Application Messages
Theses are messages sent TO the application.

## License

[MIT License](https://ColtonMcInroy.mit-license.org/) © Colton McInroy

<!-- References -->
[typescript-url]: https://github.com/Microsoft/TypeScript
[nodejs-url]: https://nodejs.org
[npm-url]: https://www.npmjs.com
[node-releases-url]: https://nodejs.org/en/download/releases

<!-- MDN -->
[array-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
[boolean-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[function-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
[map-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
[number-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
[object-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
[promise-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[regexp-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
[set-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
[string-mdn-url]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String

<!-- Badges -->
[follow-me-badge]: https://flat.badgen.net/twitter/follow/ColtonMcInroy?icon=twitter

[version-badge]: https://flat.badgen.net/npm/v/@nexgin/totaljsapplication?icon=npm
[node-version-badge]: https://flat.badgen.net/npm/node/@nexgin/totaljsapplication
[mit-license-badge]: https://flat.badgen.net/npm/license/@nexgin/totaljsapplication

[downloads-badge]: https://flat.badgen.net/npm/dm/@nexgin/totaljsapplication
[total-downloads-badge]: https://flat.badgen.net/npm/dt/@nexgin/totaljsapplication?label=total%20downloads
[packagephobia-badge]: https://flat.badgen.net/packagephobia/install/@nexgin/totaljsapplication
[bundlephobia-badge]: https://flat.badgen.net/bundlephobia/minzip/@nexgin/totaljsapplication

[daviddm-badge]: https://flat.badgen.net/david/dep/ColtonMcInroy/@nexgin/totaljsapplication
[codecov-badge]: https://flat.badgen.net/codecov/c/github/ColtonMcInroy/@nexgin/totaljsapplication?label=codecov&icon=codecov
[coveralls-badge]: https://flat.badgen.net/coveralls/c/github/ColtonMcInroy/@nexgin/totaljsapplication?label=coveralls

[codebeat-badge]: https://codebeat.co/badges/123
[codacy-badge]: https://api.codacy.com/project/badge/Grade/123
[coc-badge]: https://flat.badgen.net/badge/code%20of/conduct/pink

<!-- Links -->
[follow-me-url]: https://twitter.com/ColtonMcInroy?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=ColtonMcInroy/@nexgin/totaljsapplication

[version-url]: https://www.npmjs.com/package/@nexgin/totaljsapplication
[node-version-url]: https://nodejs.org/en/download
[mit-license-url]: https://github.com/ColtonMcInroy/@nexgin/totaljsapplication/blob/master/LICENSE

[downloads-url]: https://www.npmtrends.com/@nexgin/totaljsapplication
[packagephobia-url]: https://packagephobia.now.sh/result?p=@nexgin/totaljsapplication
[bundlephobia-url]: https://bundlephobia.com/result?p=@nexgin/totaljsapplication

[daviddm-url]: https://david-dm.org/ColtonMcInroy/@nexgin/totaljsapplication
[codecov-url]: https://codecov.io/gh/ColtonMcInroy/@nexgin/totaljsapplication
[coveralls-url]: https://coveralls.io/github/ColtonMcInroy/@nexgin/totaljsapplication?branch=master

[codebeat-url]: https://codebeat.co/projects/github-com-ColtonMcInroy-@nexgin/totaljsapplication-master
[codacy-url]: https://www.codacy.com/app/ColtonMcInroy/@nexgin/totaljsapplication?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=ColtonMcInroy/@nexgin/totaljsapplication&amp;utm_campaign=Badge_Grade
[coc-url]: https://github.com/ColtonMcInroy/@nexgin/totaljsapplication/blob/master/CODE_OF_CONDUCT.md

[application-component-url]: https://gitlab.mcinroy.info/npm/totaljsapplication/-/blob/main/components/Application.html
[module-component-url]: https://gitlab.mcinroy.info/npm/totaljsapplication/-/blob/main/components/Module.html
[totaljs-flow-url]: https://github.com/totaljs/flow