# ligature

> Service injection framework for typescript

Latest version **0.1.0** (published 2020-02-18) · MIT license · 0 weekly downloads

## Install

```sh
npm install ligature
pnpm add ligature
yarn add ligature
bun add ligature
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.0 |
| Published | 2020-02-18 |
| First published | 2017-04-28 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 31 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Patrick Wolf |
| Maintainers | patwolf |

## Links

- npm: https://www.npmjs.com/package/ligature
- Repository: https://github.com/pwwolf/ligature
- Homepage: https://github.com/pwwolf/ligature#readme
- Issues: https://github.com/pwwolf/ligature/issues
- npm.io page: https://npm.io/package/ligature

## Dependencies (2)

- [debug](https://npm.io/package/debug.md) ^4.1.1
- [reflect-metadata](https://npm.io/package/reflect-metadata.md) ^0.1.13

## Recent versions

- 0.1.0 (latest) — 2020-02-18
- 0.0.8 — 2019-03-07
- 0.0.7 — 2019-03-07
- 0.0.6 — 2017-09-18
- 0.0.5 — 2017-05-23
- 0.0.4 — 2017-05-03
- 0.0.3 — 2017-05-01
- 0.0.2 — 2017-04-28
- 0.0.1 — 2017-04-28

## README

# Ligature

Ligature is a service injection framework specifically designed for use with Typescript and Node.js.

As part of an web server startup it's common to have a few asynchronous tasks that must be performed in a particular order.
For example, an application might connect to a database, fetch some initial data, and only then is it in a state where it can serve content.

## Installation
```bash
$ npm install ligature
```

Ligature requires that `experimentalDecorators` and `emitDecoratorMetadata` both be set to true in the tsconfig.json.

## Usage

### Services
Define a service that extend the `Services` class and implement an `init` method.

```typescript
import { Service } from 'ligature';

export default class FooService extends Service {

  init () {
    console.log('FooService has been initialized');
  }
  
  doSomething () {
  
  }

}
```

That service can then be injected into other services using the `@inject` decorator.

```typescript
import { Service } from 'ligature';
import FooService from './foo';

@inject
foo: FooService;

export default class BarService extends Service {

  init () {
    console.log('BarService has been initialized');
    this.foo.doSomething();
  }
  
}
```

Then initialize all the services using the `ServiceLoader`.

```typescript
import { ServiceLoader } from 'ligature';
import FooService from './foo';
import BarService from './bar';

ServiceLoader.getInstance().init([FooService, BarService]).then(() => {
  console.log('Services started!');
}, (err) => {
  console.log('Could not start services', err);
});

```

Ligature determines the correct order in which the services must be started,
and invokes the `init` method on each on in the correct order.


Finally services can be accessed from the ServiceLoader with the `get` method.

```typescript
let foo = ServiceLoader.getInstance().get(FooService);
``` 

### Consumers
Ligature also provides a `Consumer` class, which is similar to a Service except Consumers cannot be injected into other Services or Consumers.

```typescript
import { Consumer } from 'ligature';
import FooService from './foo';

@inject
foo: FooService;

export default class FooConsumer extends Consumer {

  init () {
    console.log('FooConsumer has been initialized');
  }
  
}
```

## Passing options to Service `init` method
Any options map keyed off of the Service can be passed into the ServiceLoader's init method.

```typescript
let initOptions = new Map();
initOptions.set(Express, { foo: 'bar' });

let loader = await ServiceLoader.getInstance().init([Express, ...routes], initOptions);
```

When the corresponding Service is initialized, its `init` method will be passed the specified options.

## Advanced Usage
In addition to the `init` method, Ligature allows an optional `done` method on each service and consumer.
The `done` method is executed in reverse order from init. For example, if services A, B, and C are initialized in the order A => B => C,
then the `done` method is called in the order C => B => A.

An example of where the `done` method is useful is when creating a service to start an Express app (See the express-app in example).
There's an Express service which exposes the express app, and routes are implemented as Consumers that depend on the Express service.
Since error middleware must be registered last, that's handled within the `done` method to ensure it's registered last.

---
_Source: https://npm.io/package/ligature · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
