@ad-execute-manager/event 2.0.1

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 singcl
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.
package/README.md ADDED
@@ -0,0 +1,351 @@
1
+ # @ad-execute-manager/event
2
+
3
+ A collection of event-related utilities for JavaScript applications including EventEmitter and PubSub implementations.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ad-execute-manager/event
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - **EventEmitter**: A powerful event emitter with support for once events, max listeners, and event queuing
14
+ - **PubSub**: A simple publish-subscribe pattern implementation with automatic unsubscribe function
15
+ - **Event Queuing**: Automatically queue events when no listeners are present
16
+ - **Listener Limits**: Set maximum listeners per event to prevent memory leaks
17
+ - **Once Events**: Support for events that only fire once
18
+ - **Error Handling**: Built-in error handling for event listeners
19
+ - **TypeScript Support**: Includes TypeScript type definitions
20
+ - **Singleton Support**: EventEmitter includes static getInstance method for singleton pattern
21
+
22
+ ## Usage
23
+
24
+ ### EventEmitter
25
+
26
+ ```javascript
27
+ import { EventEmitter } from '@ad-execute-manager/event';
28
+
29
+ // Create an event emitter instance
30
+ const emitter = new EventEmitter({
31
+ maxListeners: 10,
32
+ maxQueueSize: 5,
33
+ maxOnceEvents: 5
34
+ });
35
+
36
+ // Register event listener
37
+ emitter.on('userLoggedIn', (userData) => {
38
+ console.log('User logged in:', userData);
39
+ });
40
+
41
+ // Register once event listener
42
+ emitter.once('appStarted', (appData) => {
43
+ console.log('App started:', appData);
44
+ // This listener will be automatically removed after first execution
45
+ });
46
+
47
+ // Emit events
48
+ emitter.emit('userLoggedIn', { id: 1, name: 'John' });
49
+ emitter.emit('appStarted', { version: '1.0.0' });
50
+
51
+ // Remove event listener
52
+ function onDataReceived(data) {
53
+ console.log('Data received:', data);
54
+ }
55
+
56
+ emitter.on('dataReceived', onDataReceived);
57
+ emitter.off('dataReceived', onDataReceived);
58
+
59
+ // Remove all listeners for an event
60
+ emitter.removeAllListeners('userLoggedIn');
61
+
62
+ // Remove all listeners
63
+ // emitter.removeAllListeners();
64
+
65
+ // Using singleton pattern
66
+ const singletonEmitter = EventEmitter.getInstance({
67
+ maxListeners: 15
68
+ });
69
+ ```
70
+
71
+ ### PubSub
72
+
73
+ ```javascript
74
+ import { PubSub } from '@ad-execute-manager/event';
75
+
76
+ // Create a PubSub instance
77
+ const pubsub = new PubSub();
78
+
79
+ // Subscribe to an event
80
+ const unsubscribe = pubsub.on('message', (data) => {
81
+ console.log('Message received:', data);
82
+ });
83
+
84
+ // Publish an event
85
+ pubsub.emit('message', { text: 'Hello, world!' });
86
+
87
+ // Unsubscribe using the returned function
88
+ unsubscribe();
89
+
90
+ // Subscribe to an event only once
91
+ pubsub.once('notification', (notification) => {
92
+ console.log('Notification:', notification);
93
+ // This listener will be automatically removed after first execution
94
+ });
95
+
96
+ // Publish the notification event
97
+ pubsub.emit('notification', { title: 'New Message', body: 'You have a new message' });
98
+
99
+ // Check listener count
100
+ const listenerCount = pubsub.listenerCount('message');
101
+ console.log('Message listeners:', listenerCount);
102
+
103
+ // Remove all listeners
104
+ // pubsub.removeAllListeners();
105
+ ```
106
+
107
+ ## API
108
+
109
+ ### EventEmitter
110
+
111
+ #### Constructor
112
+
113
+ ```javascript
114
+ new EventEmitter(options)
115
+ ```
116
+
117
+ - **options** (Object): Configuration options
118
+ - **maxListeners** (Number): Maximum listeners per event, default 5
119
+ - **maxQueueSize** (Number): Maximum queue size for events with no listeners, default 1
120
+ - **maxOnceEvents** (Number): Maximum once events per event, default 5
121
+
122
+ #### Methods
123
+
124
+ - **on(event, listener)**: Register an event listener
125
+ - **event** (String): Event name
126
+ - **listener** (Function): Event listener function
127
+
128
+ - **once(event, listener)**: Register a one-time event listener
129
+ - **event** (String): Event name
130
+ - **listener** (Function): Event listener function
131
+
132
+ - **emit(event, ...args)**: Emit an event
133
+ - **event** (String): Event name
134
+ - **...args** (Any): Arguments to pass to listeners
135
+
136
+ - **off(event, listenerToRemove)**: Remove an event listener
137
+ - **event** (String): Event name
138
+ - **listenerToRemove** (Function): Listener function to remove
139
+
140
+ - **removeAllListeners(event)**: Remove all listeners for an event
141
+ - **event** (String, optional): Event name, omit to remove all listeners
142
+
143
+ - **static getInstance(args)**: Get singleton instance
144
+ - **args** (Object): Constructor options
145
+ - **returns** (EventEmitter): Singleton instance
146
+
147
+ ### PubSub
148
+
149
+ #### Constructor
150
+
151
+ ```javascript
152
+ new PubSub()
153
+ ```
154
+
155
+ #### Methods
156
+
157
+ - **on(eventName, callback)**: Subscribe to an event
158
+ - **eventName** (String): Event name
159
+ - **callback** (Function): Event callback function
160
+ - **returns** (Function): Unsubscribe function
161
+
162
+ - **off(eventName, callback)**: Unsubscribe from an event
163
+ - **eventName** (String): Event name
164
+ - **callback** (Function): Callback function to remove
165
+
166
+ - **emit(eventName, ...args)**: Publish an event
167
+ - **eventName** (String): Event name
168
+ - **...args** (Any): Arguments to pass to callbacks
169
+
170
+ - **once(eventName, callback)**: Subscribe to an event once
171
+ - **eventName** (String): Event name
172
+ - **callback** (Function): Event callback function
173
+
174
+ - **listenerCount(eventName)**: Get listener count for an event
175
+ - **eventName** (String): Event name
176
+ - **returns** (Number): Listener count
177
+
178
+ - **removeAllListeners()**: Remove all listeners
179
+
180
+ ## Examples
181
+
182
+ ### Example 1: Application Event Bus
183
+
184
+ ```javascript
185
+ import { EventEmitter } from '@ad-execute-manager/event';
186
+
187
+ // Create global event bus
188
+ const eventBus = EventEmitter.getInstance({
189
+ maxListeners: 20
190
+ });
191
+
192
+ // User service
193
+ function loginUser(userData) {
194
+ // Login logic
195
+ console.log('Logging in user:', userData.username);
196
+
197
+ // Emit login event
198
+ eventBus.emit('userLoggedIn', {
199
+ user: userData,
200
+ timestamp: new Date().toISOString()
201
+ });
202
+ }
203
+
204
+ // Notification service
205
+ function setupNotifications() {
206
+ eventBus.on('userLoggedIn', (loginData) => {
207
+ console.log('Sending welcome notification to:', loginData.user.username);
208
+ // Send welcome notification
209
+ });
210
+
211
+ eventBus.on('userLoggedOut', (logoutData) => {
212
+ console.log('Updating user status to offline:', logoutData.userId);
213
+ // Update user status
214
+ });
215
+ }
216
+
217
+ // Analytics service
218
+ function setupAnalytics() {
219
+ eventBus.once('appStarted', (appData) => {
220
+ console.log('Recording app start event:', appData.version);
221
+ // Record app start analytics
222
+ });
223
+
224
+ eventBus.on('userLoggedIn', (loginData) => {
225
+ console.log('Recording login event:', loginData.user.username);
226
+ // Record login analytics
227
+ });
228
+ }
229
+
230
+ // Setup services
231
+ setupNotifications();
232
+ setupAnalytics();
233
+
234
+ // Start app
235
+ eventBus.emit('appStarted', { version: '1.0.0' });
236
+
237
+ // Login user
238
+ loginUser({ id: 1, username: 'john_doe', email: 'john@example.com' });
239
+ ```
240
+
241
+ ### Example 2: Component Communication
242
+
243
+ ```javascript
244
+ import { PubSub } from '@ad-execute-manager/event';
245
+
246
+ // Create pubsub instance for component communication
247
+ const componentBus = new PubSub();
248
+
249
+ // Header component
250
+ function Header() {
251
+ // Subscribe to user changes
252
+ const unsubscribe = componentBus.on('userChanged', (user) => {
253
+ console.log('Header: Updating user display:', user.name);
254
+ // Update header with user info
255
+ });
256
+
257
+ // Subscribe to theme changes
258
+ componentBus.on('themeChanged', (theme) => {
259
+ console.log('Header: Updating theme:', theme);
260
+ // Update header theme
261
+ });
262
+
263
+ // Cleanup function
264
+ return () => {
265
+ unsubscribe();
266
+ console.log('Header: Unsubscribed from events');
267
+ };
268
+ }
269
+
270
+ // User profile component
271
+ function UserProfile() {
272
+ // Subscribe to user changes
273
+ const unsubscribe = componentBus.on('userChanged', (user) => {
274
+ console.log('UserProfile: Updating user profile:', user.name);
275
+ // Update user profile
276
+ });
277
+
278
+ // Cleanup function
279
+ return () => {
280
+ unsubscribe();
281
+ console.log('UserProfile: Unsubscribed from events');
282
+ };
283
+ }
284
+
285
+ // Settings component
286
+ function Settings() {
287
+ // Update user
288
+ function updateUser(userData) {
289
+ console.log('Settings: Updating user');
290
+ componentBus.emit('userChanged', userData);
291
+ }
292
+
293
+ // Change theme
294
+ function changeTheme(theme) {
295
+ console.log('Settings: Changing theme to:', theme);
296
+ componentBus.emit('themeChanged', theme);
297
+ }
298
+
299
+ return {
300
+ updateUser,
301
+ changeTheme
302
+ };
303
+ }
304
+
305
+ // Initialize components
306
+ const cleanupHeader = Header();
307
+ const cleanupUserProfile = UserProfile();
308
+ const settings = Settings();
309
+
310
+ // Simulate user update
311
+ settings.updateUser({ id: 1, name: 'John Doe', email: 'john@example.com' });
312
+
313
+ // Simulate theme change
314
+ settings.changeTheme('dark');
315
+
316
+ // Cleanup components
317
+ // cleanupHeader();
318
+ // cleanupUserProfile();
319
+ ```
320
+
321
+ ### Example 3: Event Queueing
322
+
323
+ ```javascript
324
+ import { EventEmitter } from '@ad-execute-manager/event';
325
+
326
+ // Create event emitter with queueing
327
+ const emitter = new EventEmitter({
328
+ maxQueueSize: 10
329
+ });
330
+
331
+ // Emit events before listeners are registered
332
+ console.log('Emitting events before listeners...');
333
+ emitter.emit('data', { value: 1 });
334
+ emitter.emit('data', { value: 2 });
335
+ emitter.emit('data', { value: 3 });
336
+
337
+ // Register listener - will receive queued events
338
+ console.log('Registering listener...');
339
+ emitter.on('data', (data) => {
340
+ console.log('Received data:', data);
341
+ });
342
+
343
+ // Emit more events
344
+ console.log('Emitting more events...');
345
+ emitter.emit('data', { value: 4 });
346
+ emitter.emit('data', { value: 5 });
347
+ ```
348
+
349
+ ## License
350
+
351
+ MIT
@@ -0,0 +1,15 @@
1
+ export class EventEmitter {
2
+ static geInstance(args: any): EventEmitter;
3
+ constructor(options?: {});
4
+ events: {};
5
+ queues: {};
6
+ onceEvents: {};
7
+ maxListeners: any;
8
+ maxQueueSize: any;
9
+ maxOnceEvents: any;
10
+ on(event: any, listener: any): void;
11
+ once(event: any, listener: any): void;
12
+ emit(event: any, ...args: any[]): void;
13
+ off(event: any, listenerToRemove: any): void;
14
+ removeAllListeners(event: any): void;
15
+ }
@@ -0,0 +1,9 @@
1
+ export default class PubSub {
2
+ events: {};
3
+ on(eventName: any, callback: any): () => void;
4
+ off(eventName: any, callback: any): void;
5
+ emit(eventName: any, ...args: any[]): void;
6
+ once(eventName: any, callback: any): void;
7
+ listenerCount(eventName: any): any;
8
+ removeAllListeners(): void;
9
+ }
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var s in t)__webpack_require__.o(t,s)&&!__webpack_require__.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{PubSub:()=>PubSub,EventEmitter:()=>EventEmitter});class EventEmitter{constructor(e={}){this.events={},this.queues={},this.onceEvents={},this.maxListeners=e.maxListeners||5,this.maxQueueSize=e.maxQueueSize||1,this.maxOnceEvents=e.maxOnceEvents||5}on(e,t){(this.events[e]||(this.events[e]=[]),this.events[e].length>=this.maxListeners)?console.warn(`EventEmitter: Maximum listeners (${this.maxListeners}) reached for event "${e}". Listener not added.`):(this.events[e].push(t),this.queues[e]&&this.queues[e].length>0&&(this.queues[e].forEach(e=>{t(...e)}),this.queues[e]=[]))}once(e,t){let s=(...n)=>{t(...n),this.off(e,s)};(this.onceEvents[e]||(this.onceEvents[e]=new Set),this.onceEvents[e].size>=this.maxOnceEvents)?console.warn(`EventEmitter: Maximum once events (${this.maxOnceEvents}) reached for event "${e}". Once listener not added.`):(this.onceEvents[e].add(s),this.on(e,s))}emit(e,...t){this.events[e]&&this.events[e].length>0?[...this.events[e]].forEach(e=>{e(...t)}):(this.queues[e]||(this.queues[e]=[]),this.queues[e].length>=this.maxQueueSize&&(console.warn(`EventEmitter: Maximum queue size (${this.maxQueueSize}) reached for event "${e}". Oldest event removed.`),this.queues[e].shift()),this.queues[e].push(t))}off(e,t){if(!t){this.events[e]=[],this.onceEvents[e]=new Set;return}this.events[e]=this.events[e].filter(e=>e!==t),this.onceEvents[e]&&this.onceEvents[e].delete(t)}removeAllListeners(e){e?(delete this.events[e],delete this.queues[e],delete this.onceEvents[e]):(this.events={},this.queues={},this.onceEvents={})}static geInstance(e){return this._instance||(this._instance=new EventEmitter(e)),this._instance}}class PubSub{constructor(){this.events={}}on(e,t){return this.events[e]||(this.events[e]=[]),this.events[e].push(t),()=>{this.off(e,t)}}off(e,t){if(this.events[e]){if(!t){this.events[e]=[];return}this.events[e]=this.events[e].filter(e=>e!==t)}}emit(e,...t){this.events[e]&&this.events[e].forEach(s=>{try{s(...t)}catch(t){console.error(`Error in event listener for ${e}:`,t)}})}once(e,t){let s=(...n)=>{t(...n),this.off(e,s)};this.on(e,s)}listenerCount(e){return this.events[e]?this.events[e].length:0}removeAllListeners(){this.events={}}}for(var __rspack_i in exports.EventEmitter=__webpack_exports__.EventEmitter,exports.PubSub=__webpack_exports__.PubSub,__webpack_exports__)-1===["EventEmitter","PubSub"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1,2 @@
1
+ export { EventEmitter } from "./EventEmitter.js";
2
+ export { default as PubSub } from "./PubSub.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ class e{constructor(e={}){this.events={},this.queues={},this.onceEvents={},this.maxListeners=e.maxListeners||5,this.maxQueueSize=e.maxQueueSize||1,this.maxOnceEvents=e.maxOnceEvents||5}on(e,t){(this.events[e]||(this.events[e]=[]),this.events[e].length>=this.maxListeners)?console.warn(`EventEmitter: Maximum listeners (${this.maxListeners}) reached for event "${e}". Listener not added.`):(this.events[e].push(t),this.queues[e]&&this.queues[e].length>0&&(this.queues[e].forEach(e=>{t(...e)}),this.queues[e]=[]))}once(e,t){let s=(...n)=>{t(...n),this.off(e,s)};(this.onceEvents[e]||(this.onceEvents[e]=new Set),this.onceEvents[e].size>=this.maxOnceEvents)?console.warn(`EventEmitter: Maximum once events (${this.maxOnceEvents}) reached for event "${e}". Once listener not added.`):(this.onceEvents[e].add(s),this.on(e,s))}emit(e,...t){this.events[e]&&this.events[e].length>0?[...this.events[e]].forEach(e=>{e(...t)}):(this.queues[e]||(this.queues[e]=[]),this.queues[e].length>=this.maxQueueSize&&(console.warn(`EventEmitter: Maximum queue size (${this.maxQueueSize}) reached for event "${e}". Oldest event removed.`),this.queues[e].shift()),this.queues[e].push(t))}off(e,t){if(!t){this.events[e]=[],this.onceEvents[e]=new Set;return}this.events[e]=this.events[e].filter(e=>e!==t),this.onceEvents[e]&&this.onceEvents[e].delete(t)}removeAllListeners(e){e?(delete this.events[e],delete this.queues[e],delete this.onceEvents[e]):(this.events={},this.queues={},this.onceEvents={})}static geInstance(t){return this._instance||(this._instance=new e(t)),this._instance}}class t{constructor(){this.events={}}on(e,t){return this.events[e]||(this.events[e]=[]),this.events[e].push(t),()=>{this.off(e,t)}}off(e,t){if(this.events[e]){if(!t){this.events[e]=[];return}this.events[e]=this.events[e].filter(e=>e!==t)}}emit(e,...t){this.events[e]&&this.events[e].forEach(s=>{try{s(...t)}catch(t){console.error(`Error in event listener for ${e}:`,t)}})}once(e,t){let s=(...n)=>{t(...n),this.off(e,s)};this.on(e,s)}listenerCount(e){return this.events[e]?this.events[e].length:0}removeAllListeners(){this.events={}}}export{e as EventEmitter,t as PubSub};
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@ad-execute-manager/event",
3
+ "version": "2.0.1",
4
+ "description": "A collection of event-related utilities for JavaScript applications including EventEmitter and PubSub implementations.",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./dist/index.js",
9
+ "require": "./dist/index.cjs",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "main": "./dist/index.cjs",
14
+ "types": "./dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "author": {
19
+ "name": "singcl",
20
+ "email": "iambabyer@gmail.com",
21
+ "url": "https://github.com/singcl"
22
+ },
23
+ "license": "MIT",
24
+ "homepage": "https://npmjs.com/package/@ad-execute-manager/event",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/singcl/ad-execute-manager.git",
28
+ "directory": "packages/evnet"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/singcl/ad-execute-manager/issues"
32
+ },
33
+ "engines": {
34
+ "node": ">=14.0.0"
35
+ },
36
+ "keywords": [
37
+ "event-emitter",
38
+ "pubsub",
39
+ "events",
40
+ "event-bus",
41
+ "javascript",
42
+ "nodejs",
43
+ "typescript",
44
+ "event-queue",
45
+ "listener",
46
+ "singleton"
47
+ ],
48
+ "scripts": {
49
+ "build": "rslib build && tsc",
50
+ "dev": "rslib build --watch",
51
+ "format": "prettier --write .",
52
+ "lint": "eslint .",
53
+ "test": "rstest",
54
+ "prepublishOnly": "npm run build"
55
+ },
56
+ "devDependencies": {
57
+ "@babel/eslint-parser": "^7.28.5",
58
+ "@babel/preset-env": "^7.28.5",
59
+ "@eslint/js": "^9.39.1",
60
+ "@rslib/core": "^0.18.5",
61
+ "@rstest/core": "^0.7.2",
62
+ "eslint": "^9.39.2",
63
+ "eslint-plugin-import": "^2.32.0",
64
+ "globals": "^16.5.0",
65
+ "prettier": "^3.7.3",
66
+ "typescript": "^5.9.3"
67
+ }
68
+ }