Skip to content

Events (Hooks)

Overview

Events (or hooks) are a way to listen and react to the application's lifecycle events, and are used mostly to setup, teardown, and manage resources.

Sodacore Application Lifecycle

Below is a rough diagram of the Sodacore application lifecycle:

null

The Sodacore application's lifecycle is pretty simple and as follows:

  1. Construct: Firstly we initialise the configuration, and prepare a logger either by a passed in config option or use the built in.
  2. We then register all of this with the Registry so everything else can access it.
  3. We initialise the core modules of the application, like: autowire, task runner, services, etc.
  4. We setup any process signal listeners.
  5. We then call app.start which will firstly start the initialisation sequence.
  6. This will tell the autowire to find all the modules and register them with the Registry.
  7. We then initialise the events, and fire the preInit event.
  8. We then call init against all the modules, services, task runners, etc.
  9. We then fire the postInit and then the preStart event.
  10. We then start the modules, services, task runners, etc.
  11. This will fire up any services like HTTP servers, etc, and at the point the application is running.
  12. If the application throws an error, or the user closes it, we shall set an interval to force the process to stay open.
  13. We then trigger the preStop event.
  14. We shutdown all the modules, services, etc.
  15. We then trigger the postStop event.
  16. And then the application exits.

Usage

The @sodacore/core package provides a simple hook decorator that allows you to define and listen to events, and these hooks can be placed on pretty much any module, controllers, services, providers, etc.

To create a hook, let's assume we have a provider that needs to populate a list of countries, we can do this like so:

typescript
import { Provider } from '@sodacore/di';
import { Hook } from '@sodacore/core';

@Provide()
export class CountryProvider {
	private countries: string[] = [];

	@Hook('preInit')
	public async init() {
		const response = await fetch('https://restcountries.com/v3.1/all');
		const data = await response.json();
		this.countries = data.map((country: any) => country.name.common);
	}
}

The above code does the following:

  1. We create a new class called CountryProvider.
  2. We use the @Provide decorator to tell the framework that this is a provider.
  3. We create a private property called countries and set it to an empty array.
  4. We use the @Hook decorator to tell the framework that this method should be called when the preInit event is fired.
  5. When the method is called, we shall fetch a list of countries from a public API and then map the response to just the country names.

Available Events

The following events are available to listen to:

Event NameDescription
preInitThis event is fired before the application is initialised.
postInitThis event is fired after the application is initialised.
preStartThis event is fired before the application is started.
postStartThis event is fired after the application is started.
preStopThis event is fired before the application is stopped.
postStopThis event is fired just before the application exits.

Released under the Apache-2.0 License.