Have opinions about JavaScript? We want to hear them. Take the 2018 JavaScript Ecosystem Survey »

mesg-js

1.4.0 • Public • Published

MESG.js

Website - Docs - Chat - Blog

MESG.js is the official JavaScript library to interact with MESG Core.

This library can be used from an Application or a Service.

Contents

Installation

npm i mesg-js

Application

Require MESG.js as an application:

const MESG = require('mesg-js').application()

MESG Core endpoint

By default, the library connects to Core from the endpoint localhost:50052.

If you wish to set another endpoint, you must set the environmental variable MESG_ENDPOINT to the desired endpoint.

React to events

To react to events and trigger tasks, the application can use the MESG.whenEvent function. This function returns an event emitter with a possible event error.

MESG.whenEvent(event, task)
.on('error', function(error) {
  // An error has occurred
})

event definition. task definition.

React to results

To react to a task's results and trigger other tasks, the application uses the MESG.whenResult function. This function returns an event emitter with a possible event error.

MESG.whenResult(result, task)
.on('error', function(error) {
  // An error has occurred
})

result definition. task definition.

Object definition

The previous functions expect the following object definitions:

event

Key Type Default Description
serviceID String REQUIRED The event's service ID
eventKey String * Only listen for this event's key. Leave empty or set * to listen for any event from this service
filter func(eventKey: string, eventData: Object) => boolean (key, data) => true Function to filter based on the key and/or data of event

result

Key Type Default Description
serviceID String REQUIRED The result's service ID
taskKey String * Only listen for this task's key. Leave empty or set * to listen for any task's result from this service
outputKey String * Only listen for the output key. If set, taskKey is required. Leave it empty or set * to listen for any task's output from this service
tagFilters String[] [] List of tags required to process this result. All inclusive filter
filter func(outputKey: string, outputData: Object, taskKey?: string, tags?: string[]) => boolean () => true Function to filter based on the output key, output data, task key and tags of the task result

task

Key Type Default Description
serviceID String REQUIRED The task's service ID
taskKey String REQUIRED The task key to execute
tags String[] or (eventKey: string, eventData: Object) => string[] or (outputKey: string, outputData: Object, taskKey: string, tags: string[]) => string[] [] List of tags to associate with the execution. These tags can be statically set or can be generated based on event or result
inputs Object or (eventKey: string, eventData: Object) => Object or (outputKey: string, outputData: Object, taskKey: string, tags: string[]) => Object {} Input data to pass as task inputs. Inputs can be statically set or can be generated based on event or result

Example

const MESG = require('mesg-js').application()
 
// When eventX occurs, then execute start
MESG.whenEvent({
  serviceID: __EVENT_SERVICE_ID__,
  eventKey: 'eventX'
}, {
  serviceID: __TASK_SERVICE_ID__,
  taskKey: 'start',
  inputs: { foo: 'bar' }
})
.on('error', function(error) {
  // An error has occurred
})
 
// When a valid result of a task occurs, then execute taskX
MESG.whenResult({
  serviceID: __RESULT_SERVICE_ID__,
  taskKey: 'start',
  outputKey: 'valid'
}, {
  serviceID: __TASK_SERVICE_ID__,
  taskKey: 'taskX',
  inputs: function(outputKey, outputData) { return { foo: 'bar' }}
})
.on('error', function(error) {
  // An error has occurred
})

Advanced utilization

The application can use gRPC APIs directly for advanced utilization.

See the full list of available gRPC APIs.

Here some examples for the most useful gRPC APIs that your application can use:

Execute a task

const MESG = require('mesg-js').application()
 
MESG.api.ExecuteTask({
  serviceID: __TASK_SERVICE_ID__,
  taskKey: __TASK_KEY__,
  inputData: JSON.stringify(__INPUT_DATA__)
}, function (error, reply) {
  console.log('task in progress with execution id:', reply.executionID)
  ...
})

Documentation

Listen for an event

const MESG = require('mesg-js').application()
 
MESG.api.ListenEvent({
  serviceID: __TASK_SERVICE_ID__,
  eventFilter: __EVENT_KEY__
})
.on('error', function(error) {
  // An error has occurred and the stream has been closed.
})
.on('data', function(data) {
  ...
})

Documentation

Listen to a task's result

const MESG = require('mesg-js').application()
 
MESG.api.ListenResult({
  serviceID: __TASK_SERVICE_ID__,
  taskFilter: __TASK_KEY__,
  outputFilter: __OUTPUT_KEY__
})
.on('error', function(error) {
  // An error has occurred and the stream has been closed.
})
.on('data', function(data) {
  ...
})

Documentation

Service

Require MESG.js as a service:

const MESG = require('mesg-js').service()

Task

The service should call MESG.listenTask to register its available tasks to MESG Core. An object containing the tasks' key is the only parameter of this function and the tasks' functions are the values. This function returns an event emitter with possible events data and error.

MESG.listenTask({
  __TASK_1_KEY__: function (inputs, outputs) {
    // Function of the task 1
    ...
  }, 
  __TASK_2_KEY__: function (inputs, outputs) {
    // Function of the task 2
    ...
  },
  ...
})
.on('error', function (error) {
  // Handle error
})

inputs is containing the task's inputs as defined in its service.yml.

outputs is containing the task's outputs as function as defined in its service.yml. The outputs function returns a Promise and should ONLY BE CALLED ONCE per executed task with the desired data as parameters.

Example

Let's use a multiplication service as an example. Its service.yml is:

name: "service multiplication"
tasks:
  multiply:
    inputs:
      a:
        type: Number
      b:
        type: Number
    outputs:
      success:
        data:
          result:
            type: Number
      error:
        data:
          message:
            type: String

If you want more information about this file, check out the documentation on service files.

Task function

Task functions should always accept inputs and outputs as parameters.

function taskMultiply(inputs, outputs)

Inputs

The parameter inputs is an object that contains the two task's inputs: a and b.

Outputs

The parameter outputs is an object that contains the two tasks' outputs: success and error.

success and error are functions that accept an object defined by its data structure as its only parameter. Those functions return a Promise.

ONLY ONE output function should be called per task execution.

success is defined like:

outputs.success({
  result: __MULTIPLICATION_RESULT__
})
.then(function () {
  ...
})
.catch(function (error) {
  // handle error
})

And error is defined like:

outputs.error({
  message: __ERROR_MESSAGE__
})
.then(function () {
  ...
})
.catch(function (error) {
  // handle error
})

Register the task

The last step is to register the task function with MESG.

The service should call MESG.listenTask with a containing object as the key of the task, and the task's function as a value. In this example, the key is multiply and the function is taskMultiply

MESG.listenTask({
  multiply: taskMultiply
})
.on('error', function (error) {
  // Handle error
})

Javascript code

// Require MESG.js as a service
const MESG = require('mesg-js').service()
 
function taskMultiply (inputs, outputs) {
  if (inputs.a === undefined || inputs.b === undefined) {
    // There is an error. Return the error output with the message.
    outputs.error({
      message: 'a and/or b are undefined'
    })
    .catch(function (error) {
      console.error(error)
    })
  } else {
    // Return the success output with the result of the multiplication
    outputs.success({
      result: inputs.a * inputs.b
    })
    .catch(function (error) {
      console.error(error)
    })
  }
}
 
// Register the task multiply to MESG
MESG.listenTask({
  multiply: taskMultiply
})
.on('error', function (error) {
  console.error(error)
})

Event

To emit an event, the service should call the MESG.emitEvent function with the event's key and event's data as parameters. This function returns a Promise.

MESG.emitEvent(__EVENT_KEY__, __EVENT_DATA__)
.then(function () {
  ...
})
.catch(function (error) {
  // handle error
})

Example

Let's use a timer service as another example. It will emit a minute event every minute. Its service.yml is:

name: "service timer"
events:
  minute:
    timestamp:
      date:
        type: Number

And the JavaScript code:

const MESG = require('mesg-js').service()
 
function emitEvent () {
  MESG.emitEvent('minute', {
    timestamp: Date.now()
  })
  .catch(function (error) {
    console.error(error)
  })
}
setInterval(emitEvent, 60 * 1000)

Community

Contribute

Keywords

none

install

npm i mesg-js

Downloadsweekly downloads

267

version

1.4.0

license

ISC

last publish

collaborators

  • avatar
Report a vulnerability