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

lime

v0.1.1

Published

Distributed event emitter for Node.js

Downloads

14

Readme

Lime

Distributed event emitter (aka dispatcher).

Purpose

Lime is intended to use with Node.js applications running multiple processes of multiple services (such as in SOA) which need to communicate with each other. Lime uses Redis pub/sub capabilities for delivery of messages.

We realize that we do not always use both emitters and listeners in the same process. Therefore we use lazy creating Redis clients: "pub" client is created only when emit() method is used, and "sub" clients are created when on() method is used.

Installation

NPM

In your project path:

$ npm install lime

Overall concept and use case

  • You are building a cloud-based SOA application with services running on multiple threads
  • In your applications events can be described as belonging to domains or rooms, e.g. events related to specific entities — users, companies, topics, etc.
  • You are able to use a dedicated instance for Redis server
  • Parts of your application do not necessarily reside on the same network as other services and need other means of delivering events, such as net/TLS sockets
  • You want to use wildcards * when subscribing to events

Instantiating and API

var Lime = require('lime');

// instantiate using default options
var dispatcher = new Lime;

// instantiate using some custom options
var dispatcher = new Lime({
    delimeter : '~',
    redisHost : '10.0.0.29'
});

Options

Possible options for Lime are:

  • delimeter — sting "glue" used to concatenate parts of events by emitters and by subscribers
  • keyBase — base of the key for Redis; room name will be added to this string
  • defaultRoom — default room name to be used if room name was not used in join() method
  • redisHost — host of Redis server
  • redisPort — port of Redis server
  • redisOpts — options for Node.js Redis client

join(room)

Adds dispatcher to a room. Examples:

disp.join('company.12345'); // will join room "company.12345"
disp.join(); // will join default room

This method is chainable.

leave(*room)

Removes dispatcher from a room. Examples:

disp.leave('company.234'); // will leave room and will unsubscribe from corresponding Redis channel
disp.leave(); // will leave all rooms

This method is chainable.

emit(*event, payload)

Emits event to joined rooms. Examples:

disp.emit('hello-world', { foo: 'bar' }); // emits event "hello-world"
disp.emit('galaxy.123', 'hello-world', { foo: 'bar' }); // emits event "galaxy.123::hello-world" if delimeter is set to "::"

This method is chainable.

on(*event, [options], callback)

Adds listener for an event. Examples:

disp.on('hello-world', cb); // will be triggered by event "hello-world"
disp.on('company.*', cb); // will be triggered by events "company.1234", "company.Foo" etc.
disp.on('hello-world', 'galaxy.*', cb); // will be triggered by events "galaxy.123::hello-world" or "hello-world::galaxy.Milky Way", and so on
disp.on('*', cb); // will be triggered by all events

Options

  • boundary (boolean, defaults to FALSE) — if set to true, than beginning and end of input markers will be used, and entire string will need to match;
  • replace (boolean, defaults to FALSE) — if set to true, than all queued callbacks will be replaced with the current one.

For example:

disp.on('age:36', cb); // will execute
disp.on('name:alex::age:*', { boundary: true }, cb); // will execute
disp.on('name:alex', 'age:36', { boundary: true }, cb); // will execute

disp.on('age:36', { boundary: true }, cb); // will not match
disp.on('name:*', { boundary: true }, cb); // will not match

disp.emit('name:alex::age:36', 'Just say Yes');

Callbacks

Callbacks will be executed with different arguments depending on their expected arguments:

  • If callback expects 0 arguments, it will be executed without any;
  • If callback expects 1 argument, it will be executed with event payload only;
  • If callback expects 2 arguments, it will be executed with event name and event payload.

Examples:

disp.on('foo', function() { ... }); // will be executed sans arguments
disp.on('foo', function(data) { ... }); // will be executed with event payload
disp.on('foo', function(evt, data) { ... }); // will be executed with event name and payload

This method is chainable.

off(*event)

Removes listeners for provided event. Examples:

disp.off('hello-world'); // removes callbacks for "hello-world" event
disp.off('galaxy.123', 'hello-world'); // removes callbacks for "galaxy.123::hello-world" event if delimeter is set to "::"

This method is chainable.

quit()

Removes callbacks for all events and quits all currently used Redis clients.

This method is not chainable.

Examples

/*
Emitter
*/

var Lime = require('lime'),
    disp = new Lime({ redisHost: '10.0.0.1' });

disp
    .join('company:345')
    .emit('user:123', 'model:company', 'event:update', { active: false })
    .quit();
/*
Subscriber A
*/

var Lime = require('lime'),
    disp = new Lime({ redisHost: '10.0.0.1' });
/*
Subscriber B
*/

var Lime = require('lime'),
    disp = new Lime({ redisHost: '10.0.0.1' });
/*
Subscriber C
*/

var Lime = require('lime'),
    disp = new Lime({ redisHost: '10.0.0.1' });

Changelog

  • v.0.1.1 — Added options to .on() method
  • v.0.1.0 — Initial library