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

estacion

v1.2.3

Published

Event bus implementation made on top of native node events module

Downloads

908

Readme

Estacion

CircleCI Codecov NPM

Implementation of the event bus pattern via node EventEmitter class.

It can be used in the browser via events module which is automatically included by the bundlers like webpack and browserify.

How it works

Event bus is compromised of channels, channels have topics. Events are dispatched on via channels or via topics. If you subscribe to the channel you will receive events from all the topics on the channel.

If you subscribe to the topic, you will receive events that are emitted only via that particular topic.

Installation

npm install estacion

Example

const { EventBus } = require('estacion')

// or import { EventBus } from 'estacion'

// create event bus
const bus = new EventBus()

// create channels
const usersChannel = bus.channel('users')
const gamesChannel = bus.channel('games')

// create topics for the channel (optional)
const userAdded = usersChannel.topic('user_added')
const userRemoved = usersChannel.topic('user_removed')

// create topics for the channel (optional)
const gameStart = gamesChannel.topic('game_start')
const gameEnd = gamesChannel.topic('game_end')

// create listener
const listener = event => {
  console.log(event.channel)
  console.log(event.topic)
  console.log(event.payload) // custom payload from the event
}

// add listener to the channel
usersChannel.addListener(listener)

// or add listener to the channel topic
userAdded.addListener(listener)

// advanced
// subscribe to all channels and topics (more in the docs)
bus.mainChannel().addListener(listener)

// advanced
// subscribe to all channels but only for a particular topic
// now you will listen to 'game_end' on any channel
bus
  .mainChannel()
  .topic('game_end')
  .addListener(listener)

// emit event on the channel
const customPayload = {} // whatever you like
usersChannel.emit(customPayload)

// or emit event on the topic
userAdded.emit({ name: 'Sam', lastName: 'Fisher' })

skip to mainChannel explanation example on runkit

Setup is really simple:

  1. EventBus holds channels.
  2. Channels hold topics.
  3. Add listeners to channels or topics.

EventBus

EventBus is used for creating and removing channels. You can create any number of channels.

EventBus is not a singleton, you can create any number of EventBus instances.

const eventBus = new EventBus()

// create new channel or return existing channel with that name
const channel = eventBus.channel('nbc')

// remove channel
// all listeners will be automatically unsubscribed
const eventBus.removeChannel('nbc')

Channel

Channel can create and remove topics. You can add listeners directly to the channel or you can add listeners to the particular topic. When you add a listener to the channel directly, you will be notified for all events that are dispatched via topics for that channel, and also when the channel itself emits ( event.topic will be set to '*' ).

// create event bus
const eventBus = new EventBus()

// create new channel or return existing channel with that name
const channel = eventBus.channel('nbc')

// create topics on the channel
const economyTopic = channel.topic('economy')
const sportsTopic = channel.topic('sports')

// listen to all topics ( addListener directly to the channel)
const listener = event => {
  console.log(event.channel) // 'nbc'
  console.log(event.topic) // 'economy' or 'sports' or '*'
  console.log(event.payload) // custom data from the topics
}

channel.addListener(listener)

economyTopic.addListener(event => {
  console.log(event.channel) // 'nbc'
  console.log(event.topic) // 'economy'
  console.log(event.payload) // custom data from 'economy' topic
})

//remove all listeners from the channel ( including listeners on all topics)
channel.removeAllListeners()
// or particular listener
channel.removeListener(listener)

Topic

Topic is the smallest building block of the event bus system. You can only create topics via channels.

// create event bus
const eventBus = new EventBus()

// create new channel or return existing channel with that name
const channel = eventBus.channel('nbc')

// create topics on the channel
const ecologyTopic = channel.topic('ecology')

const listener = event => {
  console.log(event.channel) // 'nbc'
  console.log(event.topic) // 'ecology'
  console.log(event.payload.title) // 'Climate change is real'
  console.log(event.payload.content) // 'Lorem ipsum'
}

// listen to 'ecology' topic
ecologyTopic.addListener(listener)

// emit data
ecologyTopic.emit({ title: 'Climate change is real.', content: 'Lorem ipsum' })

channel.removeTopic('ecology') //all listeners will be automatically removed

// or remove listener directly from the topic
ecologyTopic.removeListener(listener)

Subscribe

Channel and Topic classes both inherit from the Broadcaster class, which wraps the native EventEmitter and exposes some of its methods. You can subscribe to the channel or topic via these methods:

const listener = event => {}
channelOrTopic.addListener(listener)
channelOrTopic.on(listener) // alias for addListener
channelOrTopic.prependListener(listener) // be first to be notified
channelOrTopic.once(listener) // fire only once
channelOrTopic.prependOnceListener(listener) // be first to be notified only once

Listener function accepts one parameterEventPayload .

type Listener = (event: EventPayload) => void
/**
 * Payload interface that is emited from the events
 */
interface EventPayload {
  /**
   * Channel name.
   *
   * @type {string}
   */
  channel: string
  /**
   * Topic name.
   *
   * @type {string}
   */
  topic: string
  /**
   * Payload - custom data to pass to the listeners
   *
   * @type {*}
   */
  readonly payload?: any | undefined
}

Unsubscribe

Every one of the subscribe function variations returns a function to unsubscribe from the channel or topic

const listener = event => {}
const unsubscribe = channelOrTopic.addListener(listener)
unsubscribe() // unsubscribe from the channel or topic

Or you can use one of the methods on channel or topic

const listener = event => {}
channelOrTopic.removeListener(listener)
channelOrTopic.off(listener) // alias for removeListener

Remove all listeners from the channel or topic:

channelOrTopic.removeAllListeners()

Also by destroying channel or topic, all listeners will be automatically unsubscribed. When destroying channel all topics in that channel will also be destroyed.

const eventBus = new EventBus()

// create new channel or return existing channel with that name
const channel = eventBus.channel('nbc')

// create topics on the channel
const ecologyTopic = channel.topic('ecology')

channel.addListener(event => {})
ecologyTopic.addListener(event => {})

// all listeners will be removed
channel.destroy()

// no need to call for this
ecologyTopic.destory()

EventBus main channel

There is a special channel on the EventBus that is created automatically with every EventBus instance. This special channel is used for listening to all other channels via just one subscribe call.

const eventBus = new EventBus()

const channelOne = eventBus.channel('one')
const channelTwo = eventBus.channel('two')

channelOne.emit({ name: 'Sam' })
channelTwo.emit({ name: 'Jack' })

const mainChannel = eventBus().mainChannel()

//subcribe to all channels and all topics
mainChannel.addListener(event => {
  console.log(event.channel) // 'one' or 'two'
  console.log(event.topic) // any topic from  channels 'one' or 'two'
  console.log(event.payload) // {name: 'Sam'} or {name: 'Jack'}
})

You can also subscribe to the particular topics that are emitted from any channel. In the next example, you will subscribe to the 'economy' topic on any channel and nothing else.

const eventBus = new EventBus()

const channelOne = eventBus.channel('cnn')
const channelTwo = eventBus.channel('nbc')

channelOne.topic('economy').emit()
channelTwo.topic('economy').emit()

const mainChannel = eventBus().mainChannel()

//subcribe to all channels but only 'economy` topic
mainChannel.topic('economy').addListener(event => {
  console.log(event.channel) // 'one' or 'two
  console.log(event.topic) // 'economy' from both channels
})

API docs

Estacion is written in TypeScript, auto generated API docs are available.

Author

  • Ivan Vlatković
License

This project is licensed under the MIT License - see the LICENSE file for details

Acknowledgments