@eolthar/events 1.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +65 -11
  2. package/main.js +113 -17
  3. package/package.json +4 -3
  4. package/LICENSE +0 -21
package/README.md CHANGED
@@ -1,35 +1,89 @@
1
1
  # @eolthar/events
2
- A lightweight, high-performance event system for fast and scalable projects.
2
+ A lightweight, high-performance event emitter for fast and scalable projects.
3
3
 
4
4
  ```
5
5
  npm i @eolthar/events
6
6
  ```
7
7
 
8
+ ## Benchmark
9
+ | Category | @eolthar/events | tseep | EventEmitter3 | NanoEvents | mitt |
10
+ | :-------------------------------- | --------------: | --------: | ------------: | ------------: | --------: |
11
+ | **1. Mass subscription and emit** | **4 151 932** | 3 875 026 | 3 225 172 | 3 774 587 | 3 276 026 |
12
+ | **2. Unsubscribe** | 6 198 889 | 6 286 916 | 4 384 381 | **7 885 637** | 5 295 300 |
13
+ | **3. on → emit → off** | 2 348 937 | 2 727 954 | 2 509 048 | **3 543 034** | 2 744 207 |
14
+ | **4. emit (0 arguments)** | **10 397 673** | 8 126 418 | 6 837 431 | 8 565 591 | 6 764 343 |
15
+ | **5. emit (5 arguments)** | **9 915 638** | 8 080 340 | 6 901 530 | 7 531 209 | 6 454 089 |
16
+ | **6. emit (10 arguments)** | **9 183 703** | 7 561 947 | 4 503 834 | 6 767 050 | 6 023 215 |
17
+
8
18
  ## Usage
9
19
  ```js
10
- const { createEmitter } = require("@eolthar/events");
20
+ const { Emitter } = require("@eolthar/events");
11
21
 
12
- const emitter = createEmitter();
22
+ const emitter = new Emitter();
13
23
 
14
- // Subscribe to an event
15
- const off = emitter.on("hello", (name) => {
24
+ function handler(name) {
16
25
  console.log(`Hello, ${name}!`);
17
- });
26
+ }
27
+
28
+ // Subscribe to an event
29
+ emitter.on("hello", handler);
18
30
 
19
31
  // Emit an event
20
32
  emitter.emit("hello", "Alice"); // Hello, Alice!
21
33
 
22
34
  // Unsubscribe from the event
23
- off();
35
+ emitter.off("hello", handler);
24
36
 
25
37
  // Emitting again won't call the listener
26
38
  emitter.emit("hello", "Bob"); // nothing happens
27
39
  ```
28
40
 
29
41
  ## API
30
- ### `createEmitter()`
42
+ ### `new Emitter()`
31
43
  Creates a new event emitter instance.
32
44
 
33
- #### Methods
34
- - **`on(event, listener)`** - Subscribes to a named event. Returns a function that can be called to unsubscribe.
35
- - **`emit(event, ...args)`** - Emits the specified event with any number of arguments. Calls all registered listeners in the order they were added.
45
+ ### `emitter.on(event, listener)`
46
+ Subscribes a listener to a named event.
47
+
48
+ ```js
49
+ emitter.on("data", (value) => console.log(value));
50
+ ```
51
+
52
+ ### `emitter.off(event, listener)`
53
+ Removes a specific listener from an event.
54
+
55
+ ```js
56
+ function handler(value) {
57
+ console.log(value);
58
+ }
59
+
60
+ emitter.on("data", handler);
61
+ emitter.off("data", handler);
62
+ ```
63
+
64
+ ### `emitter.once(event, listener)`
65
+ Subscribes a listener that is automatically removed after the first call. Returns the internal wrapper function, which can be passed to `off` to manually remove the listener before it fires.
66
+
67
+ ```js
68
+ emitter.once("connect", () => console.log("connected!"));
69
+ emitter.emit("connect"); // connected!
70
+ emitter.emit("connect"); // nothing happens
71
+ ```
72
+
73
+ ### `emitter.emit(event, ...args)`
74
+ Emits the specified event, calling all registered listeners in the order they were added.
75
+
76
+ ```js
77
+ emitter.emit("data", 1, 2, 3);
78
+ ```
79
+
80
+ ### `emitter.clear(event?)`
81
+ Removes all listeners for a specific event. If no event is provided, clears all events.
82
+
83
+ ```js
84
+ emitter.clear("data"); // removes all listeners for "data"
85
+ emitter.clear(); // removes everything
86
+ ```
87
+
88
+ ## License
89
+ MIT
package/main.js CHANGED
@@ -1,19 +1,115 @@
1
- const createEmitter = () => {
2
- const e = {};
3
- return {
4
- on(event, listener) {
5
- (e[event] || (e[event] = [])).push(listener);
6
- return () => {
7
- const a = e[event];
8
- const i = a.indexOf(listener);
9
- if (i !== -1) a.splice(i, 1);
10
- };
11
- },
12
- emit(event, ...args) {
13
- const a = e[event];
14
- if (a) for (let i = 0, l = a.length; i < l; i++) a[i](...args);
1
+ const forge = new Map();
2
+ const sigs = new Map([
3
+ [0, ""],
4
+ [1, "a0"]
5
+ ]);
6
+
7
+ function compile(pool, argc) {
8
+ const len = pool.length;
9
+ const stamp = len + "-" + argc;
10
+ const mold = forge.get(stamp);
11
+ if (mold !== undefined) return mold(pool);
12
+ let args = sigs.get(argc);
13
+ if (args === undefined) {
14
+ args = "a0";
15
+ for (let i = 1; i < argc; i++) args += ",a" + i;
16
+ sigs.set(argc, args);
17
+ }
18
+ let pins = "",
19
+ fire = "";
20
+ for (let i = 0; i < len; i++) {
21
+ pins += "var f" + i + "=c[" + i + "];";
22
+ fire += "f" + i + "(" + args + ");";
23
+ }
24
+ const nep = eval("(function(c){" + pins + "return function(" + args + "){" + fire + "}})");
25
+ forge.set(stamp, nep);
26
+ return nep(pool);
27
+ }
28
+
29
+ class Emitter {
30
+ constructor() {
31
+ this.events = new Map();
32
+ }
33
+
34
+ on(event, listener) {
35
+ let e = this.events.get(event);
36
+ if (!e) {
37
+ this.events.set(event, { exec: listener, arity: listener.length, pool: null });
38
+ return;
39
+ }
40
+ if (e.pool === null) {
41
+ e.pool = [e.exec, listener];
42
+ } else {
43
+ e.pool.push(listener);
44
+ }
45
+ if (listener.length > e.arity) e.arity = listener.length;
46
+ e.exec = compile(e.pool, e.arity);
47
+ }
48
+
49
+ off(event, listener) {
50
+ const e = this.events.get(event);
51
+ if (!e) return;
52
+ if (e.pool === null) {
53
+ if (e.exec === listener) this.events.delete(event);
54
+ return;
55
+ }
56
+ const pool = e.pool;
57
+ const idx = pool.indexOf(listener);
58
+ if (idx === -1) return;
59
+ const last = pool[pool.length - 1];
60
+ if (last !== listener) pool[idx] = last;
61
+ pool.pop();
62
+ if (pool.length === 1) {
63
+ const single = pool[0];
64
+ e.exec = single;
65
+ e.arity = single.length;
66
+ e.pool = null;
67
+ } else {
68
+ if (listener.length >= e.arity) {
69
+ let max = 0;
70
+ for (let i = 0; i < pool.length; i++) {
71
+ if (pool[i].length > max) max = pool[i].length;
72
+ }
73
+ e.arity = max;
74
+ }
75
+ e.exec = compile(e.pool, e.arity);
76
+ }
77
+ }
78
+
79
+ clear(event) {
80
+ if (event === undefined) {
81
+ this.events.clear();
82
+ } else {
83
+ this.events.delete(event);
84
+ }
85
+ }
86
+
87
+ once(event, listener) {
88
+ const self = this;
89
+ let called = false;
90
+ const wrapper = function () {
91
+ if (called) return;
92
+ called = true;
93
+ self.off(event, wrapper);
94
+ listener.apply(undefined, arguments);
95
+ };
96
+ Object.defineProperty(wrapper, "length", { value: listener.length });
97
+ this.on(event, wrapper);
98
+ return wrapper;
99
+ }
100
+
101
+ emit(event, a, b, c, d, f) {
102
+ const e = this.events.get(event);
103
+ if (!e) return;
104
+ const l = e.arity;
105
+ if (l < 6) {
106
+ e.exec(a, b, c, d, f);
107
+ } else {
108
+ const r = new Array(l);
109
+ for (let i = 0; i < l; i++) r[i] = arguments[i + 1];
110
+ e.exec.apply(undefined, r);
15
111
  }
16
- };
17
- };
112
+ }
113
+ }
18
114
 
19
- module.exports = { createEmitter };
115
+ module.exports = { Emitter };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eolthar/events",
3
- "description": "A lightweight, high-performance event system for fast and scalable projects.",
4
- "version": "1.0.1",
3
+ "description": "A lightweight, high-performance event emitter for fast and scalable projects.",
4
+ "version": "2.0.0",
5
5
  "main": "main.js",
6
6
  "author": "Mlad (https://github.com/eolthar)",
7
7
  "repository": "https://github.com/eolthar/events",
@@ -10,8 +10,9 @@
10
10
  "events",
11
11
  "emitter",
12
12
  "eventemitter",
13
+ "emit",
13
14
  "pubsub",
14
- "lightweight",
15
+ "fast",
15
16
  "performance"
16
17
  ]
17
18
  }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Mlad
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.