Venttiseiska
The good 'ol event emitter pattern with a few handy extras, future facing implementation and a sugary sweet API. If you're looking for the tiniest and fastest event emitter implementation keep on looking, this is not it.
Venttiseiska treats the listener as a first-class citizen that has it's own set of methods and properties. Listeners can be queried and updated at any time allowing you to easily extend the existing functionality if the need should arise. This approach sets some limits to the performance when compared to emitters with more simplistic approach.
Venttiseiska has no dependencies, works in Node.js as well as most browsers (IE9+) and is future-facing (some ES6 features such as WeakMap and WeakSet are used where appropriate with fallbacks to ES5 compatible code).
In case you're wondering, Venttiseiska is a Finnish military slang word referring to AN/PRC-77 Portable Transceiver which is used by the Finnish army, hence the name.
Enjoy, it's MIT licensed.
Install
Node
npm install venttiseiska --save-dev
Browser
<script src='venttiseiska.js'></script>
Basic usage
var emitter = new Venttiseiska();
var listener = function (msg) { console.log(msg); };
emitter.on('someEvent', listener);
emitter.emit('someEvent', ['hello']);
emitter.off('someEvent', listener);
Special features
#1: Namespaced events (aka event tags).
var emitter = new Venttiseiska();
var listener = function (msg) { console.log(msg); };
emitter.on('someEvent:tagA ', listener);
emitter.on('someEvent:tagB', listener);
emitter.emit('someEvent:tagA', ['tagA fired']);
emitter.emit('someEvent:tagB', ['tagB fired']);
emitter.emit('someEvent', ['tagA and tagB fired']);
#2: Bind, unbind and emit multiple events simultaneously.
var emitter = new Venttiseiska();
var listener = function (msg) { console.log(msg); };
emitter.on('someEvent anotherEvent', listener);
emitter.emit('someEvent anotherEvent', ['hello']);
emitter.off('someEvent anotherEvent', listener);
#3: Define listener cycles — how many times a listener can be called before it is automatically unbound.
var emitter = new Venttiseiska();
emitter.on({
events: 'someEvent',
cycles: 2,
listener: function (msg) {
console.log(msg);
}
});
emitter.emit('someEvent someEvent', ['hello']);
emitter.emit('someEvent', ['hello']);
#4. Query events and listeners.
var emitter = new Venttiseiska();
emitter.on('a b c', function (msg) {
console.log(msg);
});
var events = emitter.getEvents();
var allListeners = emitter.getListeners();
var abListeners = emitter.getListeners('a b');
#5. Update event listeners.
var emitter = new Venttiseiska();
var listeners = emitter.on('a b c', function (msg) {
console.log(msg);
});
listeners[1].update({
fn: function (msg) {
console.log(msg + ' updated');
},
tags: ['tagA', 'tagB'],
context: listeners[1],
cycles: 5
});
#6. Bind listener to specific context and switch it on the fly.
var emitter = new Venttiseiska();
var listener = function () { console.log(this); };
var contextA = 'a';
var contextB = 'b';
emitter.on('a', listener, contextA);
emitter.emit('a');
emitter.emit('a', [], contextB);
emitter.emit('a');
API
Emitter
Listener
new Venttiseiska()
Create a new event emitter instance.
var emitter = new Venttiseiska();
emitter.on( events, listener, [context] )
Bind a listener to one or more events. Returns an array of all the bound listeners in the binding order.
Arguments
- events — Array / String / Object
- Event names specified as an array or a string. When you provide multiple events as a string an empty space is considered as a delimiter for events, e.g.
'ev1 ev2 ev3'
. You can also attach tags (targetable metadata) to listeners. The tag delimiter is ':'
, e.g. 'ev1:tag1 ev2:tag2 ev3:tag1:tag2'
. - Alternatively you can provide a plain object in which case all other arguments are ignored and the arguments are searched from the provided object instead. Note that you can only set listener's cycles with the object syntax.
- listener — Function
- A listener function that will be called when any of the specified events is emitted.
- context — Anything — optional
- Listener function's context.
- cycles — Number — optional
- Default:
0
- The number of calls after which the listener is automatically unbound.
Returns — Array
An array of all the bound listeners in the binding order.
Examples
var emitter = new Venttiseiska();
var listener = function (msg) { console.log(msg); };
emitter.on('one', listener);
emitter.on('one:a', listener);
emitter.on('one:a:b:c', listener);
emitter.on('one two:a three:b:c', listener);
emitter.on(['one', 'two:a', 'three:b:c'], listener);
emitter.on('one', listener, {custom: 'context'});
emitter.on({
events: 'one',
listener: listener,
context: {custom: 'context'},
cycles: 3
});
emitter.once( events, listener, [context] )
Bind a one-off listener to one or more events. Returns an array of all the bound listeners in the binding order.
Arguments
- events — Array / String / Object
- Event names specified as an array or a string. When you provide multiple events as a string an empty space is considered as a delimiter for events, e.g.
'ev1 ev2 ev3'
. You can also attach tags (targetable metadata) to listeners. The tag delimiter is ':'
, e.g. 'ev1:tag1 ev2:tag2 ev3:tag1:tag2'
. - Alternatively you can provide a plain object in which case all other arguments are ignored and the arguments are searched from the provided object instead. Note that you can not set cycles in this method at all, this method will always set cycles to
1
.
- listener — Function
- A listener function that will be called when any of the specified events is emitted.
- context — Anything — optional
- Listener function's context.
Returns — Array
An array of all the bound listeners in the binding order.
emitter.off( [events], [target] )
Unbind event listeners. If no target is provided all listeners for the specified events will be removed. If no events are provided all listeners from all events of the instance are removed.
Arguments
- events — Array / String — optional
- Event names specified as an array or a string. When you provide multiple events as a string an empty space is considered as a delimiter for events, e.g.
'ev1 ev2 ev3'
. You can additionally target event tags to filter the removable listeners, e.g. 'ev1:tag1 ev2:tag2'
.
- target — Function / Number — optional
- Target removable event listeners by specific function or listener id. If no target is provided all listeners for the specified event will be removed.
Examples
var emitter = new Venttiseiska();
var listener = function (msg) { console.log(msg); };
emitter.on('eventA:tagA eventB:tagB', listener);
emitter.off();
emitter.off('eventA eventB');;
emitter.off('eventA eventB', listener);
emitter.off('eventA:tagA eventB:tagB', listener);
emitter.emit( events, [args], [context] )
Emit events.
Arguments
- events — Array / String
- Event names specified as an array or a string. When you provide multiple events as a string an empty space is considered as a delimiter for events, e.g.
'ev1 ev2 ev3'
. You can additionally target event tags, e.g. 'ev1:tag1 ev2:tag2'
.
- args — Array — optional
- Custom arguments for the listener functions.
- context — Anything — optional
- Custom context for the called listener functions. Overrides the possible context specified in
.on()
method.
Examples
var emitter = new Venttiseiska();
var listener = function (msgA, msgB) { console.log(msgA + ' ' + msgB); };
emitter.on('eventA:tagA eventA:tagB eventB:tagB', listener);
emitter.emit('eventA:tagA eventB', ['hello', 'beautiful']);
emitter.emit('eventA:tagB', ['Ka', 'Pow'], {custom: 'context'});
emitter.getListeners( [events] )
Get instance's listeners. Optionally you can provide a set of event names as the first argument if you want to filter the listeners. The returned event listeners are always sorted by the bind order starting from the listener that was bound earliest. Additionally the returned array never contains duplicate listeners.
Arguments
- events — Array / String — optional
- Event names specified as an array or a string. When you provide multiple events as a string an empty space is considered as a delimiter for events, e.g.
'ev1 ev2 ev3'
. You can additionally target event tags, e.g. 'ev1:tag1 ev2:tag2'
.
Returns — Array
Returns an array of event listeners, sorterd by their binding order.
Examples
var emitter = new Venttiseiska();
var listener = function (msg) { console.log(msg); };
emitter.on('eventA:tagA eventA:tagB eventB:tagB', listener);
var allListeners = emitter.getListeners();
var filteredListeners = emitter.getListeners('eventA:tagA eventB');
emitter.getEvents()
Get all events in the instance which have listeners bound to them.
Returns — Array
Returns an array of event names.
Examples
var emitter = new Venttiseiska();
var listener = function (msg) { console.log(msg); };
emitter.on('eventA eventB eventC', listener);
var events = emitter.getEvents();
new Venttiseiska.Listener( emitter, event, fn, [tags], [context], [cycles] )
Venttiseiska listener instance constructor.
Arguments
- emitter — Venttiseiska
- event — String
- fn — Function
- tags — Array — Optional
- context — Anything — Optional
- cycles — Number — Optional
Examples
var emitter = new Venttiseiska();
var fn = function (msg) { console.log(msg); };
var listener = new Venttiseiska.Listener(emitter, 'eventA', fn);
listener.off()
Unbind listener instance.
Returns — Venttiseiska.Listener
Returns the Venttiseiska.Listener instance that called the method.
Examples
var emitter = new Venttiseiska();
var fn = function (msg) { console.log(msg); };
var listener = new Venttiseiska.Listener(emitter, 'eventA', fn);
listener.off();
listener.emit( [args], [context] )
Emit listener instance.
Arguments
- args — Array — Optional
- context — Anything — Optional
Returns — Venttiseiska.Listener
Returns the Venttiseiska.Listener instance that called the method.
Examples
var emitter = new Venttiseiska();
var fn = function (msg) { console.log(msg); };
var listener = new Venttiseiska.Listener(emitter, 'eventA', fn);
listener.emit(['hello']);
listener.update( data )
Update listener's data.
Arguments
- data — Object
- data.fn — Function — optional
- data.tags — Array — optional
- data.context — Anything — optional
- data.cycles — Number — optional
- data.active — Boolean — optional
Returns — Venttiseiska.Listener
Returns the Venttiseiska.Listener instance that called the method.
Examples
var emitter = new Venttiseiska();
var fn = function (msg) { console.log(msg); };
var listener = new Venttiseiska.Listener(emitter, 'eventA', fn);
listener.update({
fn: function () { console.log('updated'); },
tags: ['tagA', 'tagB'],
context: listener,
cycles: 7
});
listener.inspect()
Inspect listener's data.
Returns — Object
Returns an object that contains the listener's information.
- id — Number
- The listener's id. Also serves as an indicator of the execution/bind order.
- emitter — Venttiseiska
- The emitter instance the listener is bound to.
- event — String
- The event's name the listener is bound to.
- fn — Function
- The listener's callback function.
- tags — Array
- The listener's tags. An array of tag names (strings).
- context — Anything
- The listener's current context that will be applied to the callback function.
- cycles — Number
- A number that defines how many times the listener can be emitted until it is automatically unbound. Defaults to
0
, which means that the cycles feature is disabled (in other words the listener has infinite cycles).
- active — Boolean
- Defines if the listener can be emitted or not.
- bound — Boolean
- Is the listener bound? If listener is not bound it means that it has been removed from the event's listeners collection.
Examples
var emitter = new Venttiseiska();
var fn = function (msg) { console.log(msg); };
var listener = new Venttiseiska.Listener(emitter, 'eventA', fn);
var listenerData = listener.inspect();