npm package: @neohelden/node
Description: Meta library for common Node.js dependencies necessary / recommended for developing Neo Sentinels.
Author: msy systems ag
Latest version: 3.0.19

# Neo SDK: Node.js

[![Build and Release SDK](https://github.com/neohelden/neo-node/actions/workflows/release.yaml/badge.svg)](https://github.com/neohelden/neo-node/actions/workflows/release.yaml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=neohelden-neo-node&metric=alert_status&token=c442f2938db6e1cd6c98817bc9038626be0a4655)](https://sonarcloud.io/dashboard?id=neohelden-neo-node)

## @neohelden/node

> Neo SDK for Node.js with some additional libraries to support the development of Neo Sentinels (NSX).

## Terminology

- **Task**: A task (or Sentinel Task) is a job processed or created by so called Sentinels.
- **Sentinel**: Fancy name for a worker consuming / producing tasks. They are usually not that evil.
- **Particle**: All tasks / messages / responses flowing through the Neo internals are generalized as „particles“. Particles can be the payload for tasks, the response to the Neo client or just some metadata. Particles have to be objects.

## Installation

```bash
yarn add @neohelden/node
```

## Configuration

The Neo SDK can be configured through environment variables (ENVs in short). The following ENVs are supported:

- `NPQ_DISABLE_AUTOCONNECT`: Set to `true` in order to prevent the SDK from autoconnecting.
- `NPQ_NAME`: A identifiable name for your Sentinel.
- `NPQ_CA`: A base64 encoded CA used for The [NATS TLS Option](https://docs.nats.io/developing-with-nats/security/tls)
- `NPQ_CERT`: A base64 encoded string used as a client certificate (signed by the `NPQ_CA`)
- `NPQ_CERT_KEY`: A base64 encoded private key belonging to the `NPQ_CERT`.

## Initialization

The SDK comes with its own healthcheck server and admi application.
This server allows to dynamically change the logging level and to check the health of the service.

To init it use:

```ts
AdminApplication.init('nsx.test');
```

## Tasks

Tasks are an integral part of the Neo plattform.

### Requesting information from a Sentinel

This method is not intended to be used anymore since it violates the principles of MQTT messaging.
The Pub/Sub model is intended to achieve async messages.
However until there are more etablished patterns for the Neo plattform, this method can be used to request information from a Sentinel.

```ts
import { TaskConnector } from '@neohelden/node';
import { IsString } from 'class-validator';
import { Expose } from 'class-transformer';

const client = new TaskConnector();

class Transmit {
  @IsString()
  test!: string;
}

class Response {
  @Expose()
  @IsString()
  test!: string;
}

await client.connect();
const response = await client.requestOne('nsx.test', new Transmit(), Response);

console.log(response.test); // 'Hello World'
```

### Receiving tasks

A subscription modal can be achieved in two modes:

1. Subscriptions which do not respond to messages. These subscriptions are purely informational and are encouraged to be used.
2. Subscriptions which respond to messages. These subscriptions are discouraged to be used since they violate the principles of MQTT messaging.

```ts
import { TaskConnector } from '@neohelden/node';
import { IsString } from 'class-validator';
import { Expose } from 'class-transformer';

const client = new TaskConnector();

class Transmit {
  @IsString()
  test!: string;
}

class Response {
  @Expose()
  @IsString()
  test!: string;
}

await client.connect();

client.subscribe(
  'nsx.test',
  Transmit,
  async (err: Error | null, transmit: Transmit) => {
    // Response will not be used

    console.log(transmit.test); // 'Hello World'
  },
);

client.respondingSubscribe('nsx.test', Transmit, async (transmit: Transmit) => {
  return new Response();
});
```

### Publishing data

By publishing data, a Sentinel can inform other Sentinels about something.

```ts
const { TaskConnector } = require('@neohelden/node');

const client = new TaskConnector();

class Transmit {
  @IsString()
  test!: string;
}

await client.connect();

const transmit = new Transmit();
transmit.test = 'Hello World';

await client.publish('nsx.test', transmit);
```

## Health

A service can inform the infrastructure if it is operational or not. This can be achieved using the admin Application. The
singelton is responsible for managing logging and health.

```ts
import AdminApplication from '../AdminApplication';
import HealthCheckResponse from '../health/HealthCheckResponse';

await AdminApplication.init('nsx.current.name');

await AdminApplication.addHealthProbe({
  call: () => HealthCheckResponse.up('test'),
}); // for health
await AdminApplication.addReadinessProbe({
  call: () => HealthCheckResponse.up('test'),
}); // for readiness

await AdminApplication.stop();
```

## Logging (optional)

> Module for logging information (based on pino).

```ts
import { LoggerFactory } from '@neohelden/node';

const logger = LoggerFactory.create('my-sentinel');

logger.info('Neo informs.');
logger.warn('Neo warns.');
logger.error('aaaah, houston?');
```

To change the logging verbosity, set the environment variable `LOG_LEVEL`. Additionally the logging can be changed while running through an HTTP server located in the `ADMIN_PORT || 8081`.

## Sentry (Exception logging)

```ts
import { Sentry } from '@neohelden/node';
sentry.initSentry({
  release: 'v0.1.0',
});
```