You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

122 lines
2.9 KiB

import { InternalService } from "./InternalService";
import assert from "assert";
/**
* Application InternalService map
*/
interface InternalServiceMap {
[name: string]: InternalService
}
/**
* The InternalService constructor type
*/
type InternalServiceConstructor<T extends Microservice = Microservice> = new (app: T) => InternalService<T>;
/**
* The main application class
*/
export class Microservice
{
/**
* Maintain a static reference to the application instance
*/
private static __instance: Microservice;
/**
* All available InternalServices
*/
protected services: InternalServiceMap = {};
/**
* Return the current application instance
*/
public static instance() {
return this.__instance;
}
/**
* Create a new application instance
*/
public constructor() {
Microservice.__instance = this;
}
// Overridable --------------------------------------------------------------------------------
/**
* Invoked when the application has finished booting
*/
protected onStart(): void|Promise<void> {}
// Application Management ----------------------------------------------------------------------
/**
* Boot the application and all of the InternalServices
*/
protected async boot() {
let InternalServices = Object.values(this.services);
return Promise.all(InternalServices.map(InternalService => InternalService.boot()));
}
/**
* Shutdown the application
*/
protected shutdown() {
let InternalServices = Object.values(this.services);
return Promise.all(InternalServices.map(InternalService => InternalService.shutdown()));
}
/**
* Start the application
*/
public async exec() {
await this.boot();
await this.onStart();
for (let InternalService of Object.values(this.services)) {
InternalService.start();
}
}
/**
* Quit the application
*/
public async quit(code: number = 0) {
await this.shutdown();
process.exit(code);
}
// InternalService Management --------------------------------------------------------------------------
/**
* Install InternalServices into the application
*/
protected installServices<T extends Microservice>(this: T, InternalServices: InternalServiceConstructor<T>[]) {
for (let InternalServiceClass of InternalServices) {
this.installService(InternalServiceClass);
}
}
/**
* Install a InternalService into the application
*/
protected installService<T extends Microservice>(this: T, InternalServiceClass: InternalServiceConstructor<T>) {
let InternalService = new InternalServiceClass(this);
this.services[InternalService.name] = InternalService;
}
/**
* Get all available InternalServices
*/
public serviceList() {
return Object.keys(this.services);
}
/**
* Get an application InternalService instance
*/
public service<T extends InternalService<Microservice>>(InternalServiceName: string) {
assert(InternalServiceName in this.services);
return <T>this.services[InternalServiceName];
}
}