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

eventbus.js

v0.1.0

Published

A minimalistic RFP library for event-driven architectures

Downloads

3

Readme

EventBus.js

A minimalistic RFP library for event-driven architectures.

Rationale

There comes a time in all good programs when components or subsystems must stop communicating directly with one another. This is often achieved via the introduction of queues between the producers of data and the consumers/processors of that data. This architectural indirection ensures that important decisions can be made with some degree of independence, and leads to systems that are easier to understand, manage, monitor and change, and make better use of computational resources, etc.
Rich Hickey

That time came for one of my side projects. I could use some of the available alternatives, but I do side projects not for the sake of productivity, but to keep my saw sharp. So I decided to reinvent the wheel.

The main difference to the existing alternatives, is that the EventBus is intended to be a central component of a conglomerate of heterogeneous units, s.t. other components are wrapped around it. Whereas the majority of the existing solutions rather work with lots of streams, which are derived from any possible source of event sequences.

Basic Concepts

An event bus is a simple medium for message exchange among independent components. It understands two primitives: events and event handlers. Events have a type and a payload. Event handlers are registered per event type. That is, a handler registered for events of type X will "see" all events of type X emitted to the event bus, but no events of different types. An exception is the type "*", which mean "all events" (see below).

The event bus should be considered as a non-deterministic untimed medium. Hence, no assumptions are allowed about:

  • the handler execution order for an emitted event;
  • the absolute timing of the event processing.

An event bus can be forked (branched). Every child inherits those events of its parent, whose types were specified during branching. The branching can be used to implicitly implement logical transactions: a component which emits and consumes its own events should always use a separate event bus if possible.

Examples

In the following example, we create an event bus and subscribe two listeners to it.

var inputs = new EventBus();
inputs.subscribe("NUMBER", function(type, payload) {
    console.log("number", payload, "was emitted to the event bus");
});
inputs.subscribe("CHARACTER", function(type, payload) {
    console.log("character", payload, "was emitted to the event bus");
});

As next, we put some events onto the even bus.

inputs.put("NUMBER", 5);
inputs.put("CHARACTER", "c");

As expected, it results in two console messages:

number 5 was emitted to the event bus
character c was emitted to the event bus

Lets derive a child instance:

var numbers = inputs.branch(["NUMBER"]);

That is, we derive from the inputs bus a new bus specifying all event types, which will be forwarded to the new branch. In this case, it's only the event type NUMBER. Now we put a listener on the new bus.

numbers.subscribe("*", function(type, payload){
    var square = payload * payload;
    console.log("square number", square, "was computed.");
});

Now we put two events t the original bus.

inputs.put("NUMBER", 7);
inputs.put("CHARACTER", "d");

The output should be:

number 7 was emitted to the event bus
square number 49 was computed.
character d was emitted to the event bus

Since only the NUMBER event was propagated to the branched bus, we square the emitted number. Putting a number to the branched bus will not affect the parent:

numbers.put("NUMBER", 8);

results in:

square number 64 was computed.

Formalism

Signatures

Event

An event consists of a type and of a payload intended for the corresponding event handler. The payload can be any valid JavaScript value. For example, this is a valid bus event:

{
    type: "someId",
    payload: { a: 2, b: 3}
}

Event Handler

An event handler receives as argument the event type, the payload and the reference of the event bus instance, on which the handler is registered. This reference can be used by the handler to emit further events. The only output accepted by the event handler is a boolean value indicating its execution status (true is successful, any other value is considered as failed execution). This status is used by the Event Bus in case if the handler was configured to fire a bounded number of times. This is a valid event handler (which, doesn't handle anything, obviously):

function(eventType, payload) {
    return true
}

There is a special type event "*" which means "all events". All handlers subscribed to the type event "*" will receive all events sent to this bus.

API

Instantiation

var bus = new EventBus()

Emitting Events

bus.put({type: "someString", payload: someObject})

or more conveniently, just

bus.put(someString, someObject)

Where:

  • eventType is the type of the emitted event;
  • payload can be any JavaScript value.

Event Handler Registration

bus.subscribe(eventType, handlerFunction, expirationCounter)

Where:

  • eventType is the type of events, which will be trigger the event handler;
  • handlerFunction is the actual handler of type described above;
  • expirationCounter is a number defining how often the handler will be fired, before it expires: if no value specified, the handler will never expire. The expiration can be controlled by the handler itself: a call is only counted if the result of the call is not equal to false (i.e., undefined counts as a successful call).

Branching

var childBus = bus.branch()
var childBus2 = bus.branch(["Type1", "Type2"])

Thi first child will receive all parent's events, whereas the second on will receive only events of the specified types. All events put to the child are invisible for the parent.

bus.close()

Closes the bus. A closed bus deletes all of its event handlers and does not react on event emitting anymore. A closed child also notifies its parent about closing, which makes the parent deleting the child reference.

Merging

var mergedBus = bus.merge(anotherBus)

merges two bus instances into a new bus, which will receive events of both bus instances. The merged bus instance is considered as a child of the instance, on which you call the merge method.

License

Distributed under ISC license.