Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
@hapi/podium
Advanced tools
@hapi/podium is an event emitter with support for multiple event channels, filters, and event arguments. It is designed to be a more powerful and flexible alternative to the built-in Node.js EventEmitter.
Basic Event Emission
This feature allows you to emit and listen to events. The example demonstrates creating a Podium instance, registering an event listener, and emitting an event.
const Podium = require('@hapi/podium');
const podium = new Podium('event');
podium.on('event', (data) => {
console.log(data);
});
podium.emit('event', { message: 'Hello, world!' });
Multiple Event Channels
This feature allows you to manage multiple event channels. The example shows how to create a Podium instance with multiple events and handle them separately.
const Podium = require('@hapi/podium');
const podium = new Podium(['event1', 'event2']);
podium.on('event1', (data) => {
console.log('Event 1:', data);
});
podium.on('event2', (data) => {
console.log('Event 2:', data);
});
podium.emit('event1', { message: 'Hello from event 1!' });
podium.emit('event2', { message: 'Hello from event 2!' });
Event Filters
This feature allows you to filter events based on custom criteria. The example demonstrates setting up a filter that only processes events of a specific type.
const Podium = require('@hapi/podium');
const podium = new Podium('event');
podium.on('event', { filter: (data) => data.type === 'type1' }, (data) => {
console.log('Filtered event:', data);
});
podium.emit('event', { type: 'type1', message: 'This will be logged' });
podium.emit('event', { type: 'type2', message: 'This will not be logged' });
Event Arguments
This feature allows you to pass multiple arguments to event listeners. The example shows how to emit an event with multiple arguments and handle them in the listener.
const Podium = require('@hapi/podium');
const podium = new Podium('event');
podium.on('event', (arg1, arg2) => {
console.log('Arguments:', arg1, arg2);
});
podium.emit('event', 'arg1', 'arg2');
The 'events' module is the built-in Node.js EventEmitter. It provides basic event emission and handling capabilities. Compared to @hapi/podium, it lacks advanced features like multiple event channels, filters, and argument handling.
EventEmitter3 is a high-performance event emitter for Node.js and the browser. It offers a similar API to the built-in EventEmitter but with better performance. However, it does not provide the advanced features of @hapi/podium, such as multiple event channels and filters.
Mitt is a tiny (~200 bytes) functional event emitter. It is designed to be simple and fast, making it suitable for small projects or performance-critical applications. Unlike @hapi/podium, it does not support advanced features like event filters and multiple channels.
Node (semi) compatible event emitter with extra features.
podium is an event emitter with support for tags, filters, channels, event update cloning,
arguments spreading, and other features useful when building large scale applications.
While node's native EventEmitter
is strictly focused on maximum performance,
it lacks many features that do not belong in the core implementation. podium is not restricted by
node's performance requirement as it is designed for application layer needs where its overhead
is largely insignificant as implementing these features will have similar cost on top of the native emitter.
Lead Maintainer - Eran Hammer
new Podium(events)
This creates a new event emitter.
const Podium = require('podium');
const podiumObject = new Podium(); // new emitter
const podiumObject2 = new Podium('event1');// creates new event and calls registerEvent()
podium.registerEvent(events)
Registers an event event1
to emitter.
podiumObject.registerEvent('event1');
//with optional parameters
podiumObject.registerEvent({
name: 'event1',
shared: true
});
Using different parameters
podium.on(criteria, listener)
Subscribe a handler to an event. Handler can be seen as a function which will be called when the event occurs.
podiumObject.registerEvent('event1');
podiumObject.on('event1', function(update) { // Way 1
console.log('inside autonomous listener without name! data:', update);
});
const listener1 = function() { // normal function object
console.log('listener1 called');
}
podiumObject.on('event1', listener1); // Way 2
podium.addListener(criteria, listener)
Same as podium.on()
.
podiumObject.addListener('event1', listener1);
podium.once(criteria, listener)
Same as calling podium.on()
with the count option set to 1. Whenever we call emit()
, listener1
will get fired
but also get removed, so that it won't get fired on call to emit()
.
podiumObject.once('event1', listener1);
podium.emit(criteria, data, [callback])
Emits an event update to all the subscribed listeners.
podiumObject.emit('event1', 'here we can send any data to listeners.');
podium.removeListener(name, listener)
Removes all listeners subscribed to a given event name matching the provided listener method.
podiumObject.removeListener('event1', listener1);
podium.removeAllListeners(name)
Removes all listeners subscribed to a given event name.
podiumObject.removeAllListeners('event1');
podium.hasListeners(name)
Returns whether an event has any listeners subscribed.
if (podiumObject.hasListeners('event1')){
console.log('this event has some listeners left');
}
else{
console.log('this event has no listeners');
}
podium.registerPodium(podiums)
Registers a podium object(emitter) to another podium object(source). Whenever any event gets registered on emitterObject
it gets registered on sourceObject
as well. But the reverse is not true.
const source1Object = new Podium('test');
const source2Object = new Podium('test');
const emitterObject = new Podium(source1Object);
emitterObject.registerPodium(source2Object);
const listener1 = function(){ // normal function
console.log('listener1 called');
}
const listener2 = function(){ // another normal function
console.log('listener1 called');
}
emitterObject.on('test', listener1); // listener1 gets registered on emitterObject, source1Object,source2Object events
source1Object.on('test', listener2); // listener2 gets registered on source1Object events only
source1Object.emit('test', 1); // runs all registered events
emitterObject.emit('test', 2);
channels
const Podium = require('podium');
const podiumObject = new Podium();
podiumObject.registerEvent([
{
name: 'event1',
channels: ['ch1', 'ch2', 'ch3', 'ch4'],
},
{
name: 'event2',
channels: ['ch1', 'ch2']
}
]);
const listener1 = (data) => {
console.log('listener1 called', data);
};
const listener2 = (data) => {
console.log('listener2 called', data);
};
podiumObject.on({
name: 'event1',
channels: ['ch1']
}, listener1);
podiumObject.on({
name: 'event1',
channels: ['ch3', 'ch4']
}, listener2);
podiumObject.on({ name: 'event1', channels: 'ch2' }, (data) => { // autonomous function
console.log('auto', data);
});
var arr = [0, 1, 2, 3, 4, 4, 5];
podiumObject.emit({
name: 'event1',
channel: 'ch3'
}, arr, function(err){
if (err){
console.log('callback error');
}
else{
console.log('callback returned true!');
}
});
clone
const Podium = require('podium');
const podiumObject = new Podium();
podiumObject.registerEvent([
{
name: 'event1',
channels: ['ch1', 'ch2'],
clone: true
},
{
name: 'event2',
channels: ['ch1', 'ch2']
}
]);
const listener1 = (data) => {
data[0] = 55;
console.log('listener1 called', data);
};
const listener2 = (data) => {
data[0] = 100;
console.log('listener2 called', data);
};
podiumObject.on({
name: 'event1',
channels: ['ch1']
}, listener1);
podiumObject.on({
name: 'event2',
channels: ['ch1']
}, listener2);
var arr = [0, 1, 2, 3, 4, 4, 5];
console.log('initially: ', arr);
podiumObject.emit({
name: 'event1',
channel: 'ch1'
}, arr, function(err){
if (err){
console.log('callback 1 error');
}
else {
console.log('callback 1 returned true!');
}
});
console.log('after event1, ch1: ', arr);
podiumObject.emit({
name: 'event2',
channel: 'ch1'
}, arr, function(err){
if (err){
console.log('callback 2 error');
}
else {
console.log('callback 2 returned true!');
}
});
console.log('after event2, ch1: ', arr);
spread
const Podium = require('podium');
const podiumObject = new Podium();
podiumObject.registerEvent([
{
name: 'event1',
channels: ['ch1', 'ch2'],
spread: true
},
{
name: 'event2',
channels: ['ch1', 'ch2']
}
]);
const listener1 = (data1, data2, data3, data4) => {
console.log('listener1 called', data1, data2, data3, data4);
};
const listener2 = (data) => {
data[0] = 100;
console.log('listener2 called', data);
};
podiumObject.on({
name: 'event1',
channels: ['ch1']
}, listener1);
podiumObject.on({
name: 'event2',
channels: ['ch1']
}, listener2);
var arr = [0, 1, 2, 3, 4, 4, 5];
console.log('initially: ', arr);
podiumObject.emit({
name: 'event1',
channel: 'ch1'
}, arr, function(err){
if (err){
console.log('callback 1 error');
}
else {
console.log('callback 1 returned true!');
}
});
console.log('after event1, ch1: ', arr);
podiumObject.emit({
name: 'event2',
channel: 'ch1'
}, arr, function(err){
if (err){
console.log('callback 2 error');
}
else {
console.log('callback 2 returned true!');
}
});
console.log('after event2, ch1: ', arr);
shared
const Podium = require('podium');
const podiumObject = new Podium();
podiumObject.registerEvent([
{
name: 'event1',
channels: ['ch1', 'ch2'],
}
]);
podiumObject.registerEvent([
{
name: 'event1',
channels: ['ch1', 'ch2'],
shared: true
}
]);
const listener2 = (data) => {
console.log('listener2 called', data);
};
podiumObject.on({
name: 'event1',
channels: ['ch1']
}, listener2);
var arr = [0, 1, 2, 3, 4, 4, 5];
podiumObject.emit({
name: 'event1',
channel: 'ch1'
}, arr, function(err){
if (err){
console.log('callback 1 error');
}
else {
console.log('callback 1 returned true!');
}
});
tag-filter
const Podium = require('podium');
const emitter = new Podium('test');
const updates = [];
emitter.on('test', (data) => updates.push({ id: 1, data }));
emitter.on({ name: 'test', filter: ['a', 'b'] }, (data) => updates.push({ id: 2, data }));
emitter.on({ name: 'test', filter: 'b' }, (data) => updates.push({ id: 3, data }));
emitter.on({ name: 'test', filter: ['c'] }, (data) => updates.push({ id: 4, data }));
emitter.on({ name: 'test', filter: { tags: ['a', 'b'], all: true } }, (data) => updates.push({ id: 5, data }));
emitter.emit({ name: 'test', tags: 'a' }, 1);
emitter.emit({ name: 'test', tags: ['b'] }, 2);
emitter.emit({ name: 'test', tags: ['d'] }, 3);
emitter.emit({ name: 'test', tags: ['a'] }, 4);
emitter.emit({ name: 'test', tags: ['a', 'b'] }, 5);
emitter.emit('test', 6, () => {
console.log(updates);
});
count
const Podium = require('podium');
const podiumObject = new Podium();
podiumObject.registerEvent('event1');
const listener1 = function(data) {
console.log('listener1 called', data);
};
podiumObject.on({
name: 'event1',
count: 2
}, listener1);
podiumObject.emit('event1', 'emit 1');
podiumObject.emit('event1', 'emit 2');
podiumObject.emit('event1', 'emit 3'); // this wont call listener1
The full API is available in the API documentation.
FAQs
Node compatible event emitter with extra features
The npm package @hapi/podium receives a total of 1,064,795 weekly downloads. As such, @hapi/podium popularity was classified as popular.
We found that @hapi/podium demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 7 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.