<commit_before>[![Build Status](https://travis-ci.org/hlapp/node-red-embedded-start.svg?branch=master)](https://travis-ci.org/hlapp/node-red-embedded-start)
[![npm](https://img.shields.io/npm/v/node-red-embedded-start.svg)](https://www.npmjs.com/package/node-red-embedded-start)
[![npm](https://img.shields.io/npm/dt/node-red-embedded-start.svg)](https://www.npmjs.com/package/node-red-embedded-start)
[![david-dm](https://david-dm.org/hlapp/node-red-embedded-start.svg)](https://david-dm.org/hlapp/node-red-embedded-start)
[![david-dm](https://david-dm.org/hlapp/node-red-embedded-start/dev-status.svg)](https://david-dm.org/hlapp/node-red-embedded-start?type=dev)

# node-red-embedded-start

When running Node-RED as an embedded application, the method to start
Node-RED (`RED.start()`) returns (more precisely, the promise it returns
resolves) before the runtime API is ready to be interacted with, resulting
in obscure internal Node-RED errors (typically, `TypeError` being thrown)
if one calls certain runtime or admin API method too early. This module
allows waiting deterministically for the runtime API for flows to be ready.

If your primary need is to interact programmatically with the flows API of
an [embedded Node-RED] instance once it starts up, then this module is for
you. One example use case likely faced by many developers (such as myself)
of nodes for Node-RED is running automatic testing for their node(s). Ideally
such testing can include testing discovery, loading, and running of nodes
by a live embedded Node-RED instance. 

_(In the wild, those who run such tests, including Node-RED itself, seem
to be using mocks of Node-RED. Not only do the mocks take a lot of code to
create, they are also at risk of diverging from what a live Node-RED instance
does. Hence, personally I would rather test manually than use a mock, or
waste my time on creating one.)_

## Installation

```
$ npm install --save node-red-embedded-start
```

If your use case is automatic testing of a Node-RED node, then you will only
need this for development and not in production, and hence use `--save-dev`
then instead of `--save`:

```
$ npm install --save-dev node-red-embedded-start
```

Note that the module does not itself have a dependency declared on `node-red`
(except for development, because it is used for testing itself). To use it,
you will have to have either a Node-RED instance (usually called `RED`), or
the `node-red` module you use for your embedded application needs to be
installed in a place where this module can find it (meaning either global,
or in the same or a higher `node_modules/` directory).

## Usage

There are two general ways to use this module. One is to insert it into the
promise chain from RED.start():

```js
var embeddedStart = require('node-red-embedded-start');
RED.start().then(embeddedStart(RED)).then((result) => {
    // result is whatever RED.start() resolved to
    // RED.node.getFlow() etc are now ready to use
}).catch((err) => {
    // theoretically, RED.start() could have rejected, but in practice
    // this isn't possible (at present) given the Node-RED code
    // so in practice embeddedStart() timed out (see below)
});
```

The other way is to inject it into `RED.start()`:

```js
var RED = require('node-red');
var embeddedStart = require('node-red-embedded-start');
embeddedStart.inject(RED);

// then use RED.start() just as you would normally
RED.start().then((result) => {
    // RED.node.getFlow() etc are now ready to use
});
```

### Usage & API details

#### Generate a wait function: `embeddedStart([RED[, timeout]])`

```js
var waitFunc = embeddedStart(RED, timeout);

RED.start().then(waitFunc).then(() => {
    // do whatever
});
```

* `RED` is the embedded Node-RED instance.
* `timeout` is the time in milliseconds after which waiting for the
  `nodes-started` event should time out. Optional, default is 30 seconds.
* If both parameters are omitted, `RED` will be loaded from the `node-red`
  module, and hence if that fails, the call will fail.

The returned function takes one optional parameter, the value that the
returned promise should resolve to. Normally, this should be the value to
which `RED.start()` resolves, so that it is passed through.

#### Call a wait function: `embeddedStart([RED, timeout,] result)`

```js
RED.start().then((result) => embeddedStart(RED, undefined, result)).then(() => {
    // do whatever
});
```

* `RED` is the embedded Node-RED instance.
* `timeout` is the time in milliseconds after which waiting for the
  `nodes-started` event should time out. Defaults to 30 seconds if undefined.
* If only the `result` parameter is provided, `RED` will be loaded from the
  `node-red` module, and hence if that fails, the call will fail.

#### Inject a wait function: `embeddedStart.inject([RED [, timeout])`

```js<commit_msg>Fixes typo in README<commit_after>[![Build Status](https://travis-ci.org/hlapp/node-red-embedded-start.svg?branch=master)](https://travis-ci.org/hlapp/node-red-embedded-start)
[![npm](https://img.shields.io/npm/v/node-red-embedded-start.svg)](https://www.npmjs.com/package/node-red-embedded-start)
[![npm](https://img.shields.io/npm/dt/node-red-embedded-start.svg)](https://www.npmjs.com/package/node-red-embedded-start)
[![david-dm](https://david-dm.org/hlapp/node-red-embedded-start.svg)](https://david-dm.org/hlapp/node-red-embedded-start)
[![david-dm](https://david-dm.org/hlapp/node-red-embedded-start/dev-status.svg)](https://david-dm.org/hlapp/node-red-embedded-start?type=dev)

# node-red-embedded-start

When running Node-RED as an embedded application, the method to start
Node-RED (`RED.start()`) returns (more precisely, the promise it returns
resolves) before the runtime API is ready to be interacted with, resulting
in obscure internal Node-RED errors (typically, `TypeError` being thrown)
if one calls certain runtime or admin API method too early. This module
allows waiting deterministically for the runtime API for flows to be ready.

If your primary need is to interact programmatically with the flows API of
an [embedded Node-RED] instance once it starts up, then this module is for
you. One example use case likely faced by many developers (such as myself)
of nodes for Node-RED is running automatic testing for their node(s). Ideally
such testing can include testing discovery, loading, and running of nodes
by a live embedded Node-RED instance. 

_(In the wild, those who run such tests, including Node-RED itself, seem
to be using mocks of Node-RED. Not only do the mocks take a lot of code to
create, they are also at risk of diverging from what a live Node-RED instance
does. Hence, personally I would rather test manually than use a mock, or
waste my time on creating one.)_

## Installation

```
$ npm install --save node-red-embedded-start
```

If your use case is automatic testing of a Node-RED node, then you will only
need this for development and not in production, and hence use `--save-dev`
then instead of `--save`:

```
$ npm install --save-dev node-red-embedded-start
```

Note that the module does not itself have a dependency declared on `node-red`
(except for development, because it is used for testing itself). To use it,
you will have to have either a Node-RED instance (usually called `RED`), or
the `node-red` module you use for your embedded application needs to be
installed in a place where this module can find it (meaning either global,
or in the same or a higher `node_modules/` directory).

## Usage

There are two general ways to use this module. One is to insert it into the
promise chain from RED.start():

```js
var embeddedStart = require('node-red-embedded-start');
RED.start().then(embeddedStart(RED)).then((result) => {
    // result is whatever RED.start() resolved to
    // RED.node.getFlow() etc are now ready to use
}).catch((err) => {
    // theoretically, RED.start() could have rejected, but in practice
    // this isn't possible (at present) given the Node-RED code
    // so in practice embeddedStart() timed out (see below)
});
```

The other way is to inject it into `RED.start()`:

```js
var RED = require('node-red');
var embeddedStart = require('node-red-embedded-start');
embeddedStart.inject(RED);

// then use RED.start() just as you would normally
RED.start().then((result) => {
    // RED.node.getFlow() etc are now ready to use
});
```

### Usage & API details

#### Generate a wait function: `embeddedStart([RED[, timeout]])`

```js
var waitFunc = embeddedStart(RED, timeout);

RED.start().then(waitFunc).then(() => {
    // do whatever
});
```

* `RED` is the embedded Node-RED instance.
* `timeout` is the time in milliseconds after which waiting for the
  `nodes-started` event should time out. Optional, default is 30 seconds.
* If both parameters are omitted, `RED` will be loaded from the `node-red`
  module, and hence if that fails, the call will fail.

The returned function takes one optional parameter, the value that the
returned promise should resolve to. Normally, this should be the value to
which `RED.start()` resolves, so that it is passed through.

#### Call a wait function: `embeddedStart([RED, timeout,] result)`

```js
RED.start().then((result) => embeddedStart(RED, undefined, result)).then(() => {
    // do whatever
});
```

* `RED` is the embedded Node-RED instance.
* `timeout` is the time in milliseconds after which waiting for the
  `nodes-started` event should time out. Defaults to 30 seconds if undefined.
* If only the `result` parameter is provided, `RED` will be loaded from the
  `node-red` module, and hence if that fails, the call will fail.

#### Inject a wait function: `embeddedStart.inject([RED [, timeout]])`

```js
{'fraction_non_alphanumeric': 0.12092110698058653, 'fraction_numerical': 0.0008261049153242462, 'mean_word_length': 4.275054466230936, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 20, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5021299', 'n_tokens_mistral': 2917, 'n_tokens_neox': 2747, 'n_words': 1172}