Compare commits

..

No commits in common. "master" and "1.0.0" have entirely different histories.

5 changed files with 29 additions and 145 deletions

View File

@ -1,7 +0,0 @@
root = true
[**]
indent_style = tab
tab_width = 4
charset = utf-8
end_of_line = lf

2
LICENSE Executable file → Normal file
View File

@ -1,4 +1,4 @@
Copyright (c) 2014-2023, Alex A. Naanou Copyright (c) 2014, Alex A. Naanou
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

100
README.md Executable file → Normal file
View File

@ -1,102 +1,2 @@
guaranteeEvents guaranteeEvents
=============== ===============
This module exports a single function that when passed an event(s) and an
[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)
compatible object will register a couple of handlers that
will provide the following functionality:
* Cache event data for each event of the given type that gets emitted.
* Call new handlers of the specified event with each of the prior event
data sets in order of event occurrence.
* Add a `.clearGuaranteedQueue(<event>)` method to the emitter to facilitate
event cache cleaning.
This is useful for modules like [glob](https://github.com/isaacs/node-glob)
that use the [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)
model to pass data to the user (see examples below).
This is similar to how state change handlers work in
[jQuery.Deferred](http://api.jquery.com/category/deferred-object/) or in
[Promise](https://promisesaplus.com/) objects.
Install
-------
```
$ npm install guarantee-events
```
Basic Examples
-------------
A synthetic example illustrating the basic functionality:
```javascript
var emitter = new (require('events').EventEmitter)
var guaranteeEvents = require('guarantee-events')
guaranteeEvents('event', emitter)
// emit some events...
emitter.emit('event', 'some data')
emitter.emit('event', 'some', 'more', 'data')
// Here the handler will be called for each event it missed...
emitter.on('event', function(){ console.log([].slice.apply(argumnts).join(' ')) })
emitter.emit('event', 'some data')
```
A real-life use-case using the excellent [glob](https://github.com/isaacs/node-glob)
utility:
```javascript
var glob = require('glob')
var guaranteeEvents = require('guarantee-events')
// build a glob object with cached 'match' and 'end' events...
var results = guaranteeEvents('match end', glob('**/*js'))
// Do stuff for some time...
// This will not miss a single result, regardless of how long it
// took to do stuff...
results.on('match', function(path){ console.log('found: '+path) })
```
Cache cleaning and use for long running emitters
------------------------------------------------
One of the dangers in using this in long running event emitters is _cache
buildup_ -- the data for each event emitted will get stored and this
might get quite large, this, if not managed, is a potential memory leak.
To deal with this issue a `.clearGuaranteedQueue(<event>)` method is
added to the emitter, this will clear the cache for a specific event.
This and has a shorthand form `.clearGuaranteedQueue('*')` that will
clear the cache for all wrapped events.
So for the above example:
```javascript
// This this will drop all the prior match data, so newly registred handlers
// will not see them...
// NOTE: this will not affect the underlaying glob object in any way.
results.clearGuaranteedQueue('match')
```

71
index.js Executable file → Normal file
View File

@ -4,13 +4,39 @@
* *
**********************************************************************/ **********************************************************************/
// Clear event cache... // Guarantee that every event handler gets every event...
// //
// This is added as a method to the emitter passed to guaranteeEvents(..)... // guaranteeEvents('event', emitter)
// guaranteeEvents('eventA eventB ...', emitter)
// guaranteeEvents(['eventA', 'eventB', ...], emitter)
// -> emitter
// //
// NOTE: his has the same event names semantics as guaranteeEvents(..) //
// NOTE: for more info see docs for guaranteeEvents(..) // This will add a .clearGuarantedQueue(..) method to the emitter that
function clearGuaranteedQueue(names){ // will clear the event queue for a specific event.
//
// Clear event(s) queue(s)...
// emitter.clearGuarantedQueue('event')
// emitter.clearGuarantedQueue('eventA eventB ...')
// emitter.clearGuarantedQueue(['eventA', 'eventB', ...])
// -> emitter
//
// Clear all queues...
// emitter.clearGuarantedQueue('*')
// -> emitter
//
//
// NOTE: the seen stack might get quite big, this is not recommended for
// long running emitters...
//
var guaranteeEvents =
module.exports =
function(names, emitter){
names = typeof(names) == typeof('str') ? names.split(/\s+/g) : names
// add ability to clear the queue...
if(emitter.clearGuarantedQueue == null){
emitter.clearGuarantedQueue = function(names){
names = names == '*' ? Object.keys(this._guaranteed_queue) names = names == '*' ? Object.keys(this._guaranteed_queue)
: typeof(names) == typeof('str') ? names.split(/\s+/g) : typeof(names) == typeof('str') ? names.split(/\s+/g)
: names : names
@ -25,37 +51,6 @@ function clearGuaranteedQueue(names){
return this return this
} }
// Guarantee that every event handler gets every event...
//
// guaranteeEvents('event', emitter)
// guaranteeEvents('eventA eventB ...', emitter)
// guaranteeEvents(['eventA', 'eventB', ...], emitter)
// -> emitter
//
//
// This will add a .clearGuaranteedQueue(..) method to the emitter that
// will clear the event queue for a specific event.
//
// Clear event(s) queue(s)...
// emitter.clearGuaranteedQueue('event')
// emitter.clearGuaranteedQueue('eventA eventB ...')
// emitter.clearGuaranteedQueue(['eventA', 'eventB', ...])
// -> emitter
//
// Clear all queues...
// emitter.clearGuaranteedQueue('*')
// -> emitter
//
//
// NOTE: the seen stack might get quite big, this is not recommended for
// long running emitters...
function guaranteeEvents(names, emitter){
names = typeof(names) == typeof('str') ? names.split(/\s+/g) : names
// add ability to clear the queue...
if(emitter.clearGuaranteedQueue == null){
emitter.clearGuaranteedQueue = clearGuaranteedQueue
emitter._guaranteed_queue = {} emitter._guaranteed_queue = {}
} }
@ -86,10 +81,6 @@ function guaranteeEvents(names, emitter){
} }
// this is the only thing we are exporting...
module.exports = guaranteeEvents
/********************************************************************** /**********************************************************************
* vim:set ts=4 sw=4 : */ * vim:set ts=4 sw=4 : */

View File

@ -1,6 +1,6 @@
{ {
"name": "guarantee-events", "name": "guaranteeEvents",
"version": "1.0.6", "version": "1.0.0",
"description": "Guarantee that every event handler gets every event...", "description": "Guarantee that every event handler gets every event...",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
@ -18,7 +18,7 @@
"event" "event"
], ],
"author": "Alex A. Naanou <alex.nanou@gmail.com> (https://github.com/flynx)", "author": "Alex A. Naanou <alex.nanou@gmail.com> (https://github.com/flynx)",
"license": "BSD-3-Clause", "license": "New BSD",
"bugs": { "bugs": {
"url": "https://github.com/flynx/guaranteeEvents/issues" "url": "https://github.com/flynx/guaranteeEvents/issues"
}, },