diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..65261d6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "singleQuote": true +} diff --git a/README.md b/README.md index 9b7eb42..b96e241 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,35 @@ With this code, when `my-event` is emited this function will be executed. The ne ``` With this code, when `my-event` is emited this function will be executed with a maximum of triggers of 3. +#### Register using wildcards +You can use wildcards to register listeners using a specific pattern. + +```js + eventBus.on('my-event.*', function () { + console.log('Inside `my-event.*`'); + }); +``` +The callback will be executed with the events like `my-event.x`. + +* `my-event.x` **will** trigger the callback ; +* `my-event.y` **will** trigger the callback ; +* `my-event` **will not** trigger the callback ; +* `my-event.x.y` **will not** trigger the callback ; + +You can also use multiple wildcards to register listeners using a specific pattern. + +```js + eventBus.on('my-event.*.name.**', function () { + console.log('my-event.*.name.**`'); + }); +``` +The callback will be executed with the events like `my-event.a.name.b.c`. + +* `my-event.a.name.b.c` **will** trigger the callback ; +* `my-event.a.name.b` **will** trigger the callback ; +* `my-event.name.b` **will not** trigger the callback ; + + #### Emit an event You can emit an event by calling the `emit` function. The arguments are the following: diff --git a/lib/js-event-bus.min.js b/lib/js-event-bus.min.js index 9bcf4ce..8c8b0d2 100644 --- a/lib/js-event-bus.min.js +++ b/lib/js-event-bus.min.js @@ -1 +1 @@ -(function(caller,bus){if(typeof exports==="object"&&typeof module==="object"){module.exports=bus()}else if(typeof exports==="object"){exports.EventBus=bus()}else{caller.EventBus=bus()}})(this,function(){var EventBus=function(){this.listeners={};this.registerListener=function(event,callback,number){var type=event.constructor.name;number=this.validateNumber(number||"any");if(type!=="Array"){event=[event]}event.forEach(function(e){if(e.constructor.name!=="String"){throw new Error("Only `String` and array of `String` are accepted for the event names!")}that.listeners[e]=that.listeners[e]||[];that.listeners[e].push({callback:callback,number:number})})};this.validateNumber=function(n){var type=n.constructor.name;if(type==="Number"){return n}else if(type==="String"&&n.toLowerCase()==="any"){return"any"}throw new Error("Only `Number` and `any` are accepted in the number of possible executions!")};this.toBeRemoved=function(info){var number=info.number;info.execution=info.execution||0;info.execution++;if(number==="any"||info.execution1){args.push(parentArgs[i])}});if(that.toBeRemoved(info)){that.listeners[eventName].splice(index,1)}callback.apply(null,args)})}}};return EventBus}); \ No newline at end of file +(function(caller,bus){if(typeof exports==="object"&&typeof module==="object"){module.exports=bus()}else if(typeof exports==="object"){exports.EventBus=bus()}else{caller.EventBus=bus()}})(this,function(){var EventBus=function(){this.listeners={};this.registerListener=function(event,callback,number){var type=event.constructor.name;number=this.validateNumber(number||"any");if(type!=="Array"){event=[event]}event.forEach(function(e){if(e.constructor.name!=="String"){throw new Error("Only `String` and array of `String` are accepted for the event names!")}that.listeners[e]=that.listeners[e]||[];that.listeners[e].push({callback:callback,number:number})})};this.validateNumber=function(n){var type=n.constructor.name;if(type==="Number"){return n}else if(type==="String"&&n.toLowerCase()==="any"){return"any"}throw new Error("Only `Number` and `any` are accepted in the number of possible executions!")};this.toBeRemoved=function(info){var number=info.number;info.execution=info.execution||0;info.execution++;if(number==="any"||info.execution=0){var newName=name.replace(/\*\*/,"([^.]+.?)+");newName=newName.replace(/\*/g,"[^.]+");var match=eventName.match(newName);if(match&&eventName===match[0]){Array.prototype.push.apply(listeners,that.listeners[name])}}}}var parentArgs=arguments;context=context||this;listeners.forEach(function(info,index){var callback=info.callback;var number=info.number;if(context){callback=callback.bind(context)}var args=[];Object.keys(parentArgs).map(function(i){if(i>1){args.push(parentArgs[i])}});if(that.toBeRemoved(info)){that.listeners[eventName].splice(index,1)}callback.apply(null,args)})}}};return EventBus}); \ No newline at end of file diff --git a/package.json b/package.json index fba21f1..10a6744 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-event-bus", - "version": "1.0.0", + "version": "1.0.1", "description": "Event bus for your Javascript applications", "homepage": "https://github.com/bcerati/js-event-bus#readme", "main": "src/index.js", @@ -17,9 +17,11 @@ "url": "https://github.com/bcerati/js-event-bus.git" }, "devDependencies": { + "es-check": "^5.1.0", + "prettier": "^1.19.1", "uglify-js": "^3.4.5" }, "scripts": { - "build": "uglifyjs ./src/index.js -o ./lib/js-event-bus.min.js" + "build": "es-check es5 src/index.js && uglifyjs ./src/index.js -o ./lib/js-event-bus.min.js" } } diff --git a/src/index.js b/src/index.js index a77eb16..3d4123a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -(function (caller, bus) { +(function(caller, bus) { if (typeof exports === 'object' && typeof module === 'object') { module.exports = bus(); } else if (typeof exports === 'object') { @@ -6,34 +6,35 @@ } else { caller.EventBus = bus(); } -})(this, function () { - var EventBus = function () { +})(this, function() { + var EventBus = function() { this.listeners = {}; - this.registerListener = function (event, callback, number) { + this.registerListener = function(event, callback, number) { var type = event.constructor.name; number = this.validateNumber(number || 'any'); - + if (type !== 'Array') { event = [event]; } - event.forEach(function (e) { + event.forEach(function(e) { if (e.constructor.name !== 'String') { - throw new Error('Only `String` and array of `String` are accepted for the event names!'); + throw new Error( + 'Only `String` and array of `String` are accepted for the event names!' + ); } - - that.listeners[e] = that.listeners[e] || []; + + that.listeners[e] = that.listeners[e] || []; that.listeners[e].push({ callback: callback, - number: number + number: number, }); - }); }; // valiodate that the number is a vild number for the number of executions - this.validateNumber = function (n) { + this.validateNumber = function(n) { var type = n.constructor.name; if (type === 'Number') { @@ -42,11 +43,13 @@ return 'any'; } - throw new Error('Only `Number` and `any` are accepted in the number of possible executions!'); + throw new Error( + 'Only `Number` and `any` are accepted in the number of possible executions!' + ); }; - // return wether or not this event needs to be removed - this.toBeRemoved = function (info) { + // return wether or not this event needs to be removed + this.toBeRemoved = function(info) { var number = info.number; info.execution = info.execution || 0; info.execution++; @@ -65,7 +68,7 @@ * @param {string} eventName - name of the event. * @param {function} callback - callback executed when this event is triggered */ - on: function (eventName, callback) { + on: function(eventName, callback) { that.registerListener.bind(that)(eventName, callback, 'any'); }, @@ -74,7 +77,7 @@ * @param {string} eventName - name of the event. * @param {function} callback - callback executed when this event is triggered */ - once: function (eventName, callback) { + once: function(eventName, callback) { that.registerListener.bind(that)(eventName, callback, 1); }, @@ -84,7 +87,7 @@ * @param {string} eventName - name of the event. * @param {function} callback - callback executed when this event is triggered */ - exactly: function (number, eventName, callback) { + exactly: function(number, eventName, callback) { that.registerListener.bind(that)(eventName, callback, number); }, @@ -92,7 +95,7 @@ * Kill an event with all it's callbacks * @param {string} eventName - name of the event. */ - die: function (eventName) { + die: function(eventName) { delete that.listeners[eventName]; }, @@ -100,7 +103,7 @@ * Kill an event with all it's callbacks * @param {string} eventName - name of the event. */ - off: function (eventName) { + off: function(eventName) { this.die(eventName); }, @@ -109,11 +112,12 @@ * @param {string} eventName - name of the event. * @param {callback} callback - the callback to remove (undefined to remove all of them). */ - detach: function (eventName, callback) { + detach: function(eventName, callback) { for (var k in that.listeners[eventName]) { if ( - that.listeners[eventName].hasOwnProperty(k) && - (that.listeners[eventName][k].callback === callback || callback === undefined) + that.listeners[eventName].hasOwnProperty(k) && + (that.listeners[eventName][k].callback === callback || + callback === undefined) ) { that.listeners[eventName].splice(k, 1); } @@ -123,7 +127,7 @@ /** * Remove all the events */ - detachAll: function () { + detachAll: function() { for (var eventName in that.listeners) { if (that.listeners.hasOwnProperty(eventName)) { this.detach(eventName); @@ -135,12 +139,31 @@ * Emit the event * @param {string} eventName - name of the event. */ - emit: function (eventName, context) { - var listeners = that.listeners[eventName] || []; + emit: function(eventName, context) { + var listeners = []; + for (name in that.listeners) { + if (that.listeners.hasOwnProperty(name)) { + if (name === eventName) { + //TODO: this lib should definitely use > ES5 + Array.prototype.push.apply(listeners, that.listeners[name]); + } + + if (name.indexOf('*') >= 0) { + var newName = name.replace(/\*\*/, '([^.]+.?)+'); + newName = newName.replace(/\*/g, '[^.]+'); + + var match = eventName.match(newName); + if (match && eventName === match[0]) { + Array.prototype.push.apply(listeners, that.listeners[name]); + } + } + } + } + var parentArgs = arguments; context = context || this; - listeners.forEach(function (info, index) { + listeners.forEach(function(info, index) { var callback = info.callback; var number = info.number; @@ -149,13 +172,11 @@ } var args = []; - Object - .keys(parentArgs) - .map(function (i) { - if (i > 1) { - args.push(parentArgs[i]); - } - }); + Object.keys(parentArgs).map(function(i) { + if (i > 1) { + args.push(parentArgs[i]); + } + }); // this event cannot be fired again, remove from the stack if (that.toBeRemoved(info)) { @@ -164,9 +185,9 @@ callback.apply(null, args); }); - } + }, }; }; return EventBus; -}); \ No newline at end of file +});