npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@nodeframe/seneca

v2.2.20

Published

seneca wrapper

Downloads

153

Readme

Seneca wrapper for ES6 and promise application

Create and maintain by Nodeframe Solution

Contact us at [email protected]

NOTE: This lib had been migrated from nfs-seneca which is officially depreciated. The development and maintenance will continue solely on this repo.

Installation

npm install @nodeframe/seneca --save

Usage

import

import nfsSeneca from '@nodeframe/seneca';

declare the seneca using this syntax

const {add, act, si} = nfsSeneca(option, transportConfig)

The last value si is the seneca object itself returned from the seneca initialization.

the implementation of si object is like so

  const si = seneca(option)

and it simply return out for you to use, you can still use si.use(), si.client(), or si.listen() as same as you would use with the official seneca object

The add and act is simply the wrapped version of si.add and si.act

Usage Example

You can declare a service with function,promise and async function

import nfsSeneca from '@nodeframe/seneca';
const {add,act,si} = nfsSeneca(config.seneca.options, config.seneca.transport);

add({...}, (args,done) => {
    done(null,{role:'With Done'});
});

add({...}, (args) => {
  return Promise.resolve('resolved');
});

add({...}, (args) => {
  return {role:'With Return'};
});

add({...}, async (args){
  return await p1();
});

Config

There's two type of config that should be pass upon initialization

The first part is the seneca option passed to the seneca initialization. This config will be passed directly to the official seneca initialization. The transportConfig is where all the magic happen.

the transport config can be like this

transports: {
 listenings: [
   {
     type: 'http',
     pins: [
       { role: 'portals', cmd: '*' }
     ],
     port: '8000',
     timeout: 30000
   }
 ],
 clients: [
   {
     type: 'http',
     pins: [
       { role: 'serviceX', cmd: '*'}
     ],
     port: '8000',
     host: process.env.APPLICATION_SERVICE || 'application_service',
     timeout: 30000
   },
   {
     type: 'http',
     pins: [
       { role: 'serviceY', cmd: '*' }
     ],
     port: '8000',
     host: process.env.USER_SERVICE || 'user_service',
     timeout: 30000
   }
 ]
}

note that this config is compatible with seneca plugins as well, for example you can use seneca-amqp-transport plugin (note that this plugin must be npm install on your main project in order to get this to work)

The example of this amqp transport config can be like so

transports: {
  listenings: [],
  clients: [
   {
     type: 'amqp',
     timeout: 5000,
     pins: [
       { role: 'USER', cmd: '*' },
       { role: 'permalinkSubmission', cmd: '*' }
     ],
     url: process.env.AMQP_URL || 'amqp://guest:[email protected]:5672'
   }
  ]
 uses: ['seneca-amqp-transport']
}

The seneca.use('seneca-amqp-transport') will be run upon initialization by this library.

Plugin

The other seneca plugin that require more initialization step shall be declared in this package, currently we have several plugin that capable for initialization simply by pushing config file to this setup (of course, you still need to npm install the plugin into the main project as well)

Mesh

This plugin will use kubernetes mesh for seneca

These npm seneca plugins are required for this plugin to work

"seneca-balance-client":
"seneca-consul-registry"
"seneca-mesh"

The mesh initialization on seneca must be run in this manner

seneca
  .use('consul-registry',{
    host: 'consul-host'
  })
  .use('mesh',{
    pins:[ //listening role
      'role:a',
      'role:b',
      'role:c',
    ],
    host:'host-name-for-this-service',
    bases:[
      'base-service-host:39999'
    ],
    discover:{
      registry:{
        active: true
      },
      multicast:{
        active: false
      }
    } //other option here
  })
  .ready(function(){
    //ready function
  })

To avoid duplicate code on your seneca initialization, these setting shall settle in your config only

const config = {
  transports: {
    type: 'mesh',
    listenings: [
      {
        pins: [
          { role: 'a', cmd: '*' },
          { role: 'b', cmd: '*' },
          { role: 'c', cmd: '*' }
        ]
      }
    ],
    clients: [],
    consul: {
      host: 'consul-host'
    },
    mesh: {
      host: 'host-name-for-this-service',
      bases: ['base-service-host:39999']
    },
    option: {
      //option in this will be merged
      discover:{
        registry:{
          active: true
        },
        multicast:{
          active: false
        }
      }
    }
  }
}

notice the mesh.host is the mandatory field that should specify about this service host name so that other service can connect to this service. The bases array is the base center service according to mesh architecture.

HealthCheck

It is important for seneca service to check if the other service to call is available or not. On the contrary, each service should provide a simple health checking for other servie to check if the communication can be made. This will help savign quite some time during debugging process.

@nodeframe/seneca try to add a mean to handle this problem. When you pass the config into @nodeframe/seneca, it will automatically read which listening pins this current service provides. It then create another special add for each pins.

For example, passing this config to @nodeframe/seneca

const seneca = nfsSeneca({}, {
  listenings: [
    {
      type: 'http',
      pins: [
        { role: 'a', cmd: '*' },
        { role: 'b', cmd: '*' },
        { role: 'c', cmd: 'cee' }
      ]
    }
  ],
  clients: [
    {
      type: 'http',
      pins: [{role: 'd', cmd: '*'}]
    }
  ]
})

passing this, the health check function will be registered to these pins

{ role: 'a', cmd: '_healthCheck' }
{ role: 'b', cmd: '_healthCheck' }

for other service you can ping to check if this service is online by running this

seneca.act({role: 'a', cmd: '_healthCheck'}, function(err, response) {
  console.log(response.result)
  //will return {timestamp: <<the current time>>, service: 'a'}
})

Note that role: c will not register any healthCheck because it could not be sure that all the pins will come into this service, hence there could be clashes on _healthCheck method. Moreover, note that the role: d will not be registered also sine it is a service that this current service will consume (not the provider).

To add manual health check to this service, you can do it by sending healthCheck config like so

const seneca = nfsSeneca({}, {
  healthCheck: ['a', 'b']
})

doing this will add cmd: _healthCheck to role a and b

Lastly, if you are not interested in the health check, you can disable it by passing

const seneca = nfsSeneca({}, {
  disableHealthCheck: true
})

HealthCheck Log Pulse

if you want to see the log pulse of _healthCheck, you should pass

const seneca = nfsSeneca({}, {
  logHealthCheckPulse: "true"
})

with this, your application will log something like this every health check pulse

run healthcheck resursively to:  payment,MAIL,property,USER,TASK,portals

USER is available at 2017-12-11T21:37:06.691Z

TASK is available at 2017-12-11T21:37:06.691Z

MAIL is available at 2017-12-11T21:37:06.691Z

payment is available at 2017-12-11T21:37:06.692Z

property is available at 2017-12-11T21:37:06.692Z

portals is available at 2017-12-11T21:37:06.695Z

Ping function

to help you debug the service, we develop a ping function that can pass the same config and ping to the client service

var ping = require('@nodeframe/seneca/libs/tool').getPing(senecaOption, transportConfig)

then, this function can be used to call to health check on the specify service

ping('a').then(function(resp) {
  console.log("resp=", resp)
})

will call to service a