Security News
Input Validation Vulnerabilities Dominate MITRE's 2024 CWE Top 25 List
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
ES6 EventEmitter class with advanced features
$ npm install arc-events --save
The following creates a new ArcEvents
object and listens for an event, and fires an event
//Initialize
var ArcEvents = require('arc-events');
let CustomEmitter = new ArcEvents();
//Bind a listener
CustomEmitter.on('change',function(_data1,_data2){
//Received my event data
});
//Emit an event
CustomEmitter.emit('change',['arg1','arg2']);
In certain edge cases, a basic EventEmitter may not suffice, the following examples highlight some more common contexts.
It is possible inside of certain abstractions, that an async data source may be receive data before the system is ready to listen for that data. In these cases setCatch()
can be used, to catch an event internally until a listener is bound to the object.
//Initialize
var ArcEvents = require('arc-events');
var EventEmitter = new ArcEvents();
//We want to 'catch' any data events inside the EventEmitter
EventEmitter.setCatch('data');
//A fake async data source
var Data = ASYNC_DATA;
//Read a buffer every 250ms and push it to the emitter
setInterval(function(){
while(Data.buffer()){
EventEmitter.emit('data',[Data.read()]);
}
},250);
//Assume the EventEmitter is propagated through the system
EventEmitter.on('data',function(_data){
//This will be fired chronologically for every previous caught event (and clear them), as well as be bound as a future listener on data
});
In a service consumer, if the service is providing events dynamically, unknown events may be critical and should be handle even if they are not actively listened for. In this way setCatchAll()
can be used to ensure no events are missed.
//We imagine an RESTful consumer, that utilizes ArcEvents
var REST = RESTFUL_CONSUMER;
//We imagine it emits HTTP codes as Events, along with Response objects
REST.on(200,function(_Response){
//OK
});
REST.on(500,function(_Response){
//Server error
});
//But we should never trust a remote server to be reliable
REST.setCatchAll(function(_event,_Response){
//In this case events without a listener propagate here for us to handle/log/swallow
});
Classically EventEmitters have a linear relationship: a listener is bound, and events fired after the listener is bound trigger the listener. If the listener is removed, those same events no longer trigger it, if another listener is added, all listeners fire chronologically in the order bound.
This is non optimal for binary states, such as loaded, or ready, or other similarily used states. In these cases, ideal behavior changes to the following:
ArcEvents supports this type of behavior with the onState()
and emitState()
methods;
//We imagine a script loader
var Scripts = SCRIPT_LOADER;
//From an external standpoint, we may want to wait on a script being loaded
Scripts.onState('specialScriptLoaded',function(){
//We know when this fires we should be safe to rely on this state
});
//From an internal standpoint we imagine our 'SpecialScript'
(function(_Scripts){
//This code is availble now, so we fire our eventState which would allow any onState listeners to be fired, and cleared
_Scripts.emitState('specialScriptLoaded');
})(Scripts);
//Again externally, we may rely on the same script
Scripts.onState('specialScriptLoaded',function(){
//In this case, as our state has already resolved, this function will automatically fire without ever being bound inside the emitter
});
Create a new ArcEvents
object. Requires new
Clears the EventEmitter back to it's original state, effectively a reset
for the Emitter.
listener:Function
)Set a special listener to catch all events that do not have any listener bound. Can be unset by passing undefined
as the listener argument.
event:String
)Tell the EventEmitter to collect all emitted events of a certain type. These events will be stored internally until a listener is bound, at which point the listener will be called chronologically for each stored event, clearing it out of the EventEmitter.
event:String, listener:Function [,customId:Mixed]
)Set a callback to listen for an event being emitted. customId is an optional id, that can technically be anything that in turn can be used by the clean()
method later to clear all listeners matching that id. In the event that no customId is set on()
will return an id that was internally generated.
state:String,listener:Function
)Set a callback to listen for a state. If that state already exists, the listener will not be bound internally and simply immediately fire, otherwise it will be bound internally until the state is emitted at which point it will be fired and cleared.
state:String
)Check to see whether a state has fired. Returns true
or false
event:String, listener:Function [,customId:Mixed]
)Set a callback to listen for an event being emitted. When the listener fires, it will automatically be removed internally as a listener and will no longer fire on subsequent events.
event:String, listener:Function
)customId:Mixed
)These methods are for cleanup:
removeListener()
requires the original function to remove the listenerclean()
uses an id to remove the listener//Example of removing a listener
var ArcEvents = require('arc-events');
var eventEmitter = new ArcEvents();
var listener = function(){
//A listener
};
//We bind a listener
eventEmitter.on('event',listener);
//But we can remove it because we have a reference to the original listener
eventEmitter.removeListener('event',listener);
//If we do the following
var internalId = eventEmitter.on('event',function(){
//We do not have reference to this, so will not be able to use removeListener
});
//Instead we use clean, and the internalId
eventEmitter.clean(internalId);
event:String
)If a string
is passed in, remove all listeners for that event. If undefined
is passed in, remove all internal listeners.
event:String
)Get an array of all listeners bound to an event.
event:String [,arguments:Array]
)Emit an event, in order to trigger all listeners bound to the event. Arguments is an optional array of the argument list that will be passed into the listener.
state:String
)Emit a state and trigger/clear all listeners bound to that state. Additionally set the internal state to true
allowing future onState()
listeners to immediately fire.
state:String
)Clear a state, allowing listeners to once more be bound internally waiting for the state to fire.
target:Object
)A static method for extending existing objects. Existing object will have all of the ArcEvents methods bound to it, and will overwrite properties that are already set that have the same name.
//Example
var ArcEvents = require('arc-events');
var OtherClass = new OtherClass();
ArcEvents.mixin(OtherClass);
//Now we can access an event scope for that object
OtherClass.on('what?',()=>{});
OtherClass.emit('what?');
$ npm test
FAQs
Independent Events class
The npm package arc-events receives a total of 1,239 weekly downloads. As such, arc-events popularity was classified as popular.
We found that arc-events demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.