├── patches ├── ons.patch.eve.js ├── once.patch.eve.js ├── on.patch.eve.js └── last.patch.eve.js ├── core.eve.js ├── LICENSE ├── index.html └── README.md /patches/ons.patch.eve.js: -------------------------------------------------------------------------------- 1 | Eve.prototype.ons = function (obj) { 2 | Object.entries(obj).forEach(([event, fns]) => 3 | Array.isArray(fns) ? this.on(event, ...fns) : this.on(event, fns) 4 | ); 5 | }; 6 | -------------------------------------------------------------------------------- /patches/once.patch.eve.js: -------------------------------------------------------------------------------- 1 | Eve.prototype.once = function (event, fn) { 2 | const self = this; 3 | this.on(event, function once(...data) { 4 | self.off(event, once); 5 | fn(...data); 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /patches/on.patch.eve.js: -------------------------------------------------------------------------------- 1 | Eve.prototype.on = function (event, ...fns) { 2 | ((e) => fns.map((f) => e.add(f)))( 3 | (this.eventMap.has(event) 4 | ? this.eventMap 5 | : this.eventMap.set(event, new Set()) 6 | ).get(event) 7 | ); 8 | }; 9 | -------------------------------------------------------------------------------- /patches/last.patch.eve.js: -------------------------------------------------------------------------------- 1 | Eve.prototype.last = function (event, ...data) { 2 | const fns = this.eventMap.get(event); 3 | if (!fns || fns.size === 0) return; 4 | 5 | let lastFn = null; 6 | for (const fn of fns) { 7 | lastFn = fn; 8 | } 9 | lastFn(...data); 10 | }; 11 | -------------------------------------------------------------------------------- /core.eve.js: -------------------------------------------------------------------------------- 1 | class Eve { 2 | constructor() { 3 | this.eventMap = new Map(); 4 | } 5 | on(event, fn) { 6 | (this.eventMap.has(event) 7 | ? this.eventMap 8 | : this.eventMap.set(event, new Set()) 9 | ) 10 | .get(event) 11 | .add(fn); 12 | } 13 | off(event, fn) { 14 | this.eventMap.has(event) && 15 | (fn ? this.eventMap.get(event).delete(fn) : this.eventMap.delete(event)); 16 | } 17 | emit(event, ...data) { 18 | const fns = this.eventMap.get(event); 19 | if (!fns) return; 20 | for (const fn of fns) { 21 | fn(...data); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Silvan Büdenbender 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |benchmarking...
56 | 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eve, the tiny event emitter. 2 | 3 | I stumbled upon [eev](https://github.com/chrisdavies/eev) which claims to be tiny and fast. 4 | 5 | It is tiny and fast but not quite as tiny as it could be so I made something even more tiny. 6 | 7 | core.eve.js is all the fundemental API an event emitter needs and even faster. 8 | See benchmark [here](https://silvancodes.github.io/eve). 9 | 10 | ## How to get it. 11 | It is so simple and tiny the easiest way would be to just copy and paste the source and eventually modify it to your need. 12 | 13 | Another possibility is to use jsDelivr: https://cdn.jsdelivr.net/gh/SilvanCodes/eve/core.eve.js 14 | 15 | For the patches: 16 | - https://cdn.jsdelivr.net/gh/SilvanCodes/eve/patches/on.patch.eve.min.js 17 | - https://cdn.jsdelivr.net/gh/SilvanCodes/eve/patches/ons.patch.eve.min.js 18 | - https://cdn.jsdelivr.net/gh/SilvanCodes/eve/patches/once.patch.eve.min.js 19 | - https://cdn.jsdelivr.net/gh/SilvanCodes/eve/patches/last.patch.eve.min.js 20 | 21 | Having the following setup pulls in core and applies the patches: 22 | 23 | ```html 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ``` 34 | 35 | ## How to use it. 36 | 37 | Create an event emitter. 38 | 39 | ```js 40 | const eve = new Eve(); 41 | ``` 42 | 43 | Setup and register event handlers. 44 | 45 | ```js 46 | const logData = data => console.log('Got some data:', data); 47 | const logAdded = (a, b) => console.log(a + b); 48 | 49 | eve.on('my-event-name', logData); 50 | eve.on('add-and-log', logAdded); 51 | ``` 52 | 53 | Then go and fire your events. 54 | 55 | ```js 56 | eve.emit('my-event-name', 'test'); // output: Got some data: test 57 | 58 | // multiple arguments are possible after event name 59 | eve.emit('add-and-log', 5, 6); // output: 11 60 | ``` 61 | 62 | Finally when you are done unregister the handlers. 63 | 64 | ```js 65 | // unregister a single handler 66 | eve.off('my-event-name', logData); 67 | 68 | // unregister all handlers at once by just providing the event name 69 | eve.off('log-and-add'); 70 | ``` 71 | 72 | ## Patches. 73 | > ons.patch.eve.js needs on.patch.eve.js to be applied first. 74 | 75 | There is a patches folder which offers some extensions to the essential API. 76 | 77 | They really are convenience functions so I did not include them in the core. 78 | 79 | Apply the patches as you see fit. 80 | 81 | ### on.patch.eve.js 82 | 83 | This patch allows for the following syntax: 84 | 85 | ```js 86 | const handler1 = data => console.log(data); 87 | const handler2 = data => console.log(data); 88 | const handler3 = data => console.log(data); 89 | 90 | // register multiple handlers at once 91 | eve.on('my-event-name', handler1, handler2, handler3); 92 | ``` 93 | 94 | ### ons.patch.eve.js 95 | 96 | This patch allows for the following syntax: 97 | 98 | ```js 99 | const handler1 = data => console.log(data); 100 | const handler2 = data => console.log(data); 101 | const handler3 = data => console.log(data); 102 | 103 | // supply handlers as an object 104 | eve.ons({ 105 | // key is event, value is handler 106 | 'my-event-name': handler1, 107 | // array of handlers is fine too 108 | 'my-other-event': [handler2, handler3] 109 | }); 110 | ``` 111 | 112 | ### once.patch.eve.js 113 | 114 | This patch allows for the following syntax: 115 | 116 | ```js 117 | const handler1 = data => console.log(data); 118 | 119 | // this handler will only fire once and then unregister itself 120 | eve.once('my-event-name', handler1); 121 | ``` 122 | 123 | ### last.patch.eve.js 124 | 125 | This patch allows to only invoke the most recent registered handler: 126 | 127 | ```js 128 | const handler1 = data => console.log('handler1', data); 129 | const handler2 = data => console.log('handler2', data); 130 | 131 | eve.on('my-event-name', handler1); 132 | eve.on('my-event-name', handler2); 133 | 134 | // this will only trigger handler2 135 | eve.last('my-event-name', 'data'); // output: 'handler2 data' 136 | ``` 137 | --------------------------------------------------------------------------------