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

@turanga/dispatcher

v0.1.0

Published

Event dispatcher to loosly couple packages and enable their communication needs

Downloads

3

Readme

Dispatcher

Bringing together various application packages requires a common foundation for communication needs. For that reason events serve best to decouple packages while allowing to hook into state changes.

Installation

npm install js-turanga/dispatcher

Dispatcher

The Dispatcher class is like the heartbeat of an event notification system. Events and listeners Creating an event dispatcher instance is as easy as:

const { Dispatcher } = require( "./dispatcher/dist" );

const dispatcher = new Dispatcher;

Supported capabilities by the event dispatcher

// register one event (as string) or multiple events (as array of strings) for listener
dispatcher.listen( events, listener );

// unregister event listeners
dispatcher.unlisten( events, listener );

// subscribe subscriber class which must implement getSubscribedEvents to collect events with listeners
dispatcher.subscribe( subscriber );

// unregister subscriber
dispatcher.unsubscribe( subscriber );

// dispatch event class (payload is then event itself) or event name as string with optional payload argument
dispatcher.dispatch( event, payload );

// check if any listener is registered for event (or all listeners when argument left away )
dispatcher.hasListeners( event );

// get event listeners for event (or all listeners when argument left away )
dispatcher.getListeners( event );

Events

It is common to dispatch event classes for communication between application packages. An event class serves as container for related datasets. Depending on the use case, building event classes for any event might be too much of overhead. What is common for both cases, they share an event name and event data.

Event Naming

When an event is dispatched, it’s identified by a unique name, which any number of listeners might be listening to. The unique event name can be any string, but optionally follows a few naming conventions:

  • use only lowercase letters, numbers, dots (.) and underscores (_);
  • prefix names with a namespace followed by a dot (e.g. order., user.);
  • end names with a verb that indicates what action has been taken (e.g. order.placed, order_placed).

To ensure these naming conventions, the event dispatcher includes some checks and transformations:

  • for event classes with a 'name' property, the name property is transformed to snake case
  • for event classes without a 'name' property, event names are built by class name (without namespace), transformed to snake case e.g. event class 'User\UserProfileCreated' is transformed to event name 'user_profile_created'
  • for events registered and dispatches as string, a snake case transformation is applied e.g. event named 'userProfileCreated' is transformed to event name 'user_profile_created'

Event Payload

Events dispatched as event classes as well as in the lightweight mode are capable of transfering payload.

Event playload for dispatches event classes:

// dispatching event class
dispatcher.dispatch(new Event(subject, [..]))

// event name: 'event'
// event payload: event class itself

Please consider the event class chapter for further details about the generic event class

Event playload for lightweight mode:

// dispatching simple event
dispatcher.dispatch('event', [...])

// event name: 'event'
// event payload: [...]

Event Class

This package provides an Event base class for convenience for those who wish to use just one event object throughout their application. It is suitable for most purposes straight out of the box, because it follows the standard observer pattern where the event object encapsulates an event ‘subject’, but has the addition of optional extra arguments. The Event class provides a method "stopPropagation". To ask for the events propagation state please use the isPropagationStopped method. Any listener waiting to be processed for that event will not get notified by the event dispatcher.

For using the Event class provided by this package just apply

const { Event } = require( "./dispatcher/dist" );

const Event = new Event;

Provides Event class methods are:

__construct(subject, args)	Constructor takes the event subject and any arguments;
getSubject() 								Get the subject;
setArguments() 							Set event argument as key/value array
getArguments() 							Get argument by key or any arguments if none is given
hasArgument() 							Returns true if the argument key exists;

To take advantage of all provided event capabilities please extend from the packages Event class

class CustomEvens extends Event
{
}

Listeners

To take advantage of an existing event, you need to connect a listener to the dispatcher so that it can be notified when the event is dispatched. A call to the dispatcher’s listen() method associates a listener to an event. The listen() method takes up to two arguments:

  • event name (string) that this listener wants to listen to;
  • an event listener to be executed when the specified event is dispatched;

Listener Callables

Event listeners can be provided in various configurations:

  • as function. A listener provided as function is executed when the event gets dispatched

      dispatcher.listen('foo', (arg) => { ... do something ... }; );
  • an object implementing an __invoke method. The invoke method is executed on the object when the event gets dispatched

      dispatcher.listen('foo', { ... __invoke() { ... do something ... } } );
  • an array with an object as first and method as second argument. The method will get called on a dispatched event.

      dispatcher.listen('foo', [{ ... methodX() { ... do something ... } }, 'methodX'] );
  • an array with a function as first and method as second argument. This configuration is supposed for lazy listeners while the function returns an object. The provided method will later be called on the object for a dispatched event.

Wildcard Listeners

The event dispatcher provided by this package supports wildcard events for more generic listeners. E.g.

  • a listener registered for order.created acts only on this event
  • a listener registered for order.* acts on all events machting the dotted prefix notation like order.processed, order.closed

Subscribers

The most common way to listen to an event is to register an event listener with the dispatcher. This listener can listen to one or more events and is notified each time those events are dispatched. Another way to listen to events is via an event subscriber. An event subscriber is a javascript class that’s able to tell the dispatcher exactly which events it should subscribe on one or more listeners. A subscriber class must implement a getSubscribedEvents method and must return an object with event/listeners:

class CustomSubscriber
{
	...

getSubscribedEvents() {
    return {
        'pre.foo': 'preFoo', 
        'post.foo': ['postFoo1', 'postFoo2']
    }
}

...

preFoo(payload, dispatcher) {}

postFoo1(payload, dispatcher) {}

postFoo2(payload, dispatcher) {}

The dispatcher invokes the registered methods if an event gets dispatched. The dispatcher allows for two listener arguments

  • payload: event class itself or payload provided when registered an event via the listen method
  • dispatcher: the dispatcher instance to allow for advanced use cases