@web-state/event-bus
A Simple event bus for publish-subscribe (pub/sub) design pattern.
Install
Node or web bundler (webpack, rollup, esbuild, etc)
$ npm install @web-state/event-bus
ESM
import { EventBus } from '@web-state/event-bus`
CommonJS
const EventBus = require('@web-state/event-bus').EventBus
Web browser with script tag
ESM
<script type="module">
import { EventBus } from 'https://cdn.jsdelivr.net/npm/@web-state/event-bus/dist/esm/event-bus.js'
</script>
Global fallback
<script
nomodule
src="https://cdn.jsdelivr.net/npm/@web-state/event-bus/dist/browser/event-bus.js"
></script>
<script nomodule>
// Script adds global WebState namespace and exposes
// EventBus through the global namespace.
const eventBus = new WebState.EventBus()
</script>
Usage
// index.mjs
import { EventBus } from '@web-state/event-bus'
const eventBus = new EventBus()
// Subscribe to all events by not
// passing in a specific eventType to listen for
const globalUnsubscribe = eventBus.subscribe((e) => {
console.log('Global Listener:')
console.log(e)
})
// Listen for "cool" events
const coolUnsubscribe = eventBus.subscribe('cool', (e) => {
console.log('Cool Listener:')
console.log(e.detail.name)
})
// triggers global listener
eventBus.publish('SomeEvent', 'Event Payload')
// triggers global and cool listeners
eventBus.publish('cool', {
name: 'some name',
more: 'another property',
})
// unsubscribe to events
globalUnsubscribe()
coolUnsubscribe()
// Neither global nor cool listeners are triggered.
eventBus.publish('cool', 'message')
$ node index.mjs
// prints
Global Listener:
{ type: "SomeEvent", detail: "Event Payload"}
Global Listener:
{
type: "cool",
detail: { name: "some name", more: "another property" }
}
Cool Listener
some name
Currying
EventBus methods support currying
// index.mjs
import { EventBus } from '@web-state/event-bus'
const eventBus = new EventBus()
// create a subscriber for the newTodo event
const newTodoSubscriber = eventBus.subscribe('newTodo')
// later on subscribe to the newTodo event
const newTodoUnsubscribe = newTodoSubscriber(({ detail }) => {
console.log(`A new todo item: ${detail}`)
})
// create a newTodo event publisher
const newTodoPublish = eventBus.publish('newTodo')
// later on publish newTodo event with a payload
newTodoPublish('Clean room')
// unsubscribe
newTodoUnsubscribe()
$ node index.mjs
// prints
A new todo item: Clean room
Bounded methods
Since instance methods of the EventBus class are bound to the instance itself they support being passed around to callback based APIs.
const eventBus = new EventBus()
someCallbackBasedAPI(eventBus.subscribe, eventBus.publish)