@maxax/x-plugins-mitt 1.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.
package/README.md ADDED
@@ -0,0 +1,507 @@
1
+ # @maxax/x-plugins-mitt
2
+
3
+ A lightweight event bus wrapper based on [mitt](https://github.com/developit/mitt) for Maxax projects. This package provides a powerful event bus system designed for micro-frontend architectures, supporting communication between master and slave applications.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@maxax/x-plugins-mitt.svg)](https://www.npmjs.com/package/@maxax/x-plugins-mitt)
6
+ [![License](https://img.shields.io/npm/l/@maxax/x-plugins-mitt.svg)](LICENSE)
7
+
8
+ ## Features
9
+
10
+ - **Lightweight**: Built on top of mitt, minimal footprint
11
+ - **Type-safe**: Full TypeScript support with generic types
12
+ - **Micro-frontend Ready**: Built-in support for master-slave application communication
13
+ - **Flexible**: Multiple ways to get event bus instances (singleton, factory)
14
+ - **Powerful**: Supports wildcards, once events, and comprehensive event management
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @maxax/x-plugins-mitt mitt
20
+ # or
21
+ pnpm add @maxax/x-plugins-mitt mitt
22
+ # or
23
+ yarn add @maxax/x-plugins-mitt mitt
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ### Basic Usage
29
+
30
+ ```typescript
31
+ import { getEventBus, createEventBus } from '@maxax/x-plugins-mitt'
32
+
33
+ // Option 1: Use singleton instance
34
+ const eventBus = getEventBus()
35
+
36
+ // Option 2: Create a new instance
37
+ const eventBus = createEventBus()
38
+
39
+ // Define event types
40
+ interface MyEvents {
41
+ userLoggedIn: { userId: string; username: string }
42
+ notification: { message: string; type: 'info' | 'warning' | 'error' }
43
+ [key: string]: any
44
+ }
45
+
46
+ // Subscribe to events
47
+ eventBus.on('userLoggedIn', (data) => {
48
+ console.log(`User ${data.username} logged in with ID: ${data.userId}`)
49
+ })
50
+
51
+ // Publish events
52
+ eventBus.emit('userLoggedIn', { userId: '123', username: 'john' })
53
+
54
+ // Unsubscribe
55
+ const unsubscribe = eventBus.on('notification', (data) => {
56
+ console.log('Notification:', data.message)
57
+ })
58
+ unsubscribe()
59
+ ```
60
+
61
+ ### Manager Usage (Micro-frontend)
62
+
63
+ For micro-frontend architectures, use the `MaxEventBusManager` to coordinate events between master and slave applications:
64
+
65
+ ```typescript
66
+ import { getMaxEventBusManager } from '@maxax/x-plugins-mitt'
67
+
68
+ // Get manager instance
69
+ const manager = getMaxEventBusManager()
70
+
71
+ // ============ Master Application ============
72
+
73
+ // Listen for events from any slave application
74
+ manager.onAnySlave('dataUpdated', (data, appName) => {
75
+ console.log(`Received data update from ${appName}:`, data)
76
+ })
77
+
78
+ // Broadcast to all applications
79
+ manager.broadcast('globalNotification', {
80
+ message: 'System will restart in 5 minutes',
81
+ severity: 'warning'
82
+ })
83
+
84
+ // ============ Slave Application ============
85
+
86
+ // Send event to master
87
+ manager.toMaster('slaveReady', { appName: 'dashboard', timestamp: Date.now() })
88
+
89
+ // Send event to specific slave
90
+ manager.toSlave('orderApp', 'newOrder', { orderId: 'ORD-001', amount: 99.99 })
91
+
92
+ // Listen to master events
93
+ manager.onMaster('configChanged', (data) => {
94
+ console.log('New configuration:', data)
95
+ })
96
+ ```
97
+
98
+ ## API Reference
99
+
100
+ ### MaxEventBus
101
+
102
+ The core event bus class.
103
+
104
+ #### Constructor
105
+
106
+ ```typescript
107
+ constructor()
108
+ ```
109
+
110
+ Creates a new event bus instance.
111
+
112
+ #### Methods
113
+
114
+ ##### emit
115
+
116
+ ```typescript
117
+ emit<Key extends keyof MaxEvents>(type: Key, data: MaxEvents[Key]): void
118
+ ```
119
+
120
+ Publishes an event with data.
121
+
122
+ ```typescript
123
+ eventBus.emit('userCreated', { userId: '123', email: 'user@example.com' })
124
+ ```
125
+
126
+ ##### emitWithout
127
+
128
+ ```typescript
129
+ emitWithout<Key extends keyof MaxEvents>(type: ...): void
130
+ ```
131
+
132
+ Publishes an event without data.
133
+
134
+ ##### on
135
+
136
+ ```typescript
137
+ on<Key extends keyof MaxEvents>(event: Key, callback: Handler<MaxEvents[Key]>): () => void
138
+ ```
139
+
140
+ Subscribes to an event. Returns an unsubscribe function.
141
+
142
+ ```typescript
143
+ const unsubscribe = eventBus.on('message', (data) => {
144
+ console.log('Received message:', data)
145
+ })
146
+
147
+ // Later, unsubscribe
148
+ unsubscribe()
149
+ ```
150
+
151
+ ##### once
152
+
153
+ ```typescript
154
+ once<Key extends keyof MaxEvents>(event: Key, callback: Handler<MaxEvents[Key]>): () => void
155
+ ```
156
+
157
+ Subscribes to an event that only fires once.
158
+
159
+ ```typescript
160
+ eventBus.once('initComplete', () => {
161
+ console.log('Initialization complete!')
162
+ })
163
+ ```
164
+
165
+ ##### onBoth
166
+
167
+ ```typescript
168
+ onBoth(handler: WildcardHandler<MaxEvents>): () => void
169
+ ```
170
+
171
+ Subscribes to all events (wildcard).
172
+
173
+ ```typescript
174
+ eventBus.onBoth((event, data) => {
175
+ console.log(`Event "${event}" fired with data:`, data)
176
+ })
177
+ ```
178
+
179
+ ##### off
180
+
181
+ ```typescript
182
+ off<Key extends keyof MaxEvents>(event: Key, callback?: Handler<MaxEvents[Key]>): void
183
+ ```
184
+
185
+ Unsubscribes from an event. If no callback provided, removes all listeners for that event.
186
+
187
+ ##### clear
188
+
189
+ ```typescript
190
+ clear(): void
191
+ ```
192
+
193
+ Removes all event listeners.
194
+
195
+ ### Factory Functions
196
+
197
+ ```typescript
198
+ // Get or create singleton instance
199
+ function getEventBus(): MaxEventBus
200
+
201
+ // Create a new instance
202
+ function createEventBus(): MaxEventBus
203
+
204
+ // Reset singleton instance
205
+ function resetEventBus(): void
206
+ ```
207
+
208
+ ### MaxEventBusManager
209
+
210
+ Event bus manager for micro-frontend architectures.
211
+
212
+ #### Methods
213
+
214
+ ##### getMasterBus
215
+
216
+ ```typescript
217
+ getMasterBus(): MaxEventBus
218
+ ```
219
+
220
+ Returns the master application event bus.
221
+
222
+ ##### registerSlaveBus
223
+
224
+ ```typescript
225
+ registerSlaveBus(appName: string, slaveEventBus: MaxEventBus): void
226
+ ```
227
+
228
+ Registers a slave application event bus.
229
+
230
+ ##### unregisterSlaveBus
231
+
232
+ ```typescript
233
+ unregisterSlaveBus(appName: string): void
234
+ ```
235
+
236
+ Unregisters a slave application.
237
+
238
+ ##### broadcast
239
+
240
+ ```typescript
241
+ broadcast<K extends string>(event: K, data?: any): void
242
+ ```
243
+
244
+ Broadcasts an event to all applications (master + all slaves).
245
+
246
+ ##### toMaster
247
+
248
+ ```typescript
249
+ toMaster<K extends string>(event: K, data?: any): void
250
+ ```
251
+
252
+ Sends an event to the master application.
253
+
254
+ ##### toSlave
255
+
256
+ ```typescript
257
+ toSlave<K extends string>(appName: string, event: K, data?: any): void
258
+ ```
259
+
260
+ Sends an event to a specific slave application.
261
+
262
+ ##### toSlaves
263
+
264
+ ```typescript
265
+ toSlaves<K extends string>(appNames: string[], event: K, data?: any): void
266
+ ```
267
+
268
+ Sends an event to multiple slave applications.
269
+
270
+ ##### onMaster
271
+
272
+ ```typescript
273
+ onMaster<K extends string>(event: K, callback: (data: any) => void): () => void
274
+ ```
275
+
276
+ Listens to events from the master application.
277
+
278
+ ##### onSlave
279
+
280
+ ```typescript
281
+ onSlave<K extends string>(appName: string, event: K, callback: (data: any) => void): () => void
282
+ ```
283
+
284
+ Listens to events from a specific slave application.
285
+
286
+ ##### onAnySlave
287
+
288
+ ```typescript
289
+ onAnySlave<K extends string>(event: K, callback: (data: any, appName: string) => void): () => void
290
+ ```
291
+
292
+ Listens to events from any slave application. Callback receives the data and app name.
293
+
294
+ ##### getRegisteredApps
295
+
296
+ ```typescript
297
+ getRegisteredApps(): string[]
298
+ ```
299
+
300
+ Returns a list of registered slave application names.
301
+
302
+ ##### destroy
303
+
304
+ ```typescript
305
+ destroy(): void
306
+ ```
307
+
308
+ Destroys the manager and all associated event buses.
309
+
310
+ ## Advanced Examples
311
+
312
+ ### Complete Micro-frontend Setup
313
+
314
+ ```typescript
315
+ // master.ts - Main application
316
+ import { getMaxEventBusManager, createEventBus } from '@maxax/x-plugins-mitt'
317
+
318
+ const masterBus = getMaxEventBusManager()
319
+
320
+ // Listen for all slave events
321
+ masterBus.onAnySlave('*', (event, data, appName) => {
322
+ console.log(`[${appName}] ${event}:`, data)
323
+ })
324
+
325
+ // Send configuration to all apps
326
+ masterBus.broadcast('configUpdate', {
327
+ theme: 'dark',
328
+ language: 'en',
329
+ apiUrl: 'https://api.example.com'
330
+ })
331
+
332
+ // Handle slave registration
333
+ masterBus.onSlave('reactApp', 'register', (data) => {
334
+ console.log('React app registered:', data)
335
+ })
336
+
337
+ // -------------------------------------------------
338
+
339
+ // slave-react.ts - React micro-frontend
340
+ import { createEventBus, getMaxEventBusManager } from '@maxax/x-plugins-mitt'
341
+
342
+ const slaveBus = createEventBus()
343
+ const manager = getMaxEventBusManager()
344
+
345
+ // Register with master
346
+ manager.registerSlaveBus('reactApp', slaveBus)
347
+
348
+ // Notify master we're ready
349
+ manager.toMaster('register', {
350
+ name: 'React Dashboard',
351
+ version: '1.0.0',
352
+ components: ['Chart', 'Table', 'Form']
353
+ })
354
+
355
+ // Listen for config changes
356
+ manager.onMaster('configUpdate', (config) => {
357
+ applyConfig(config)
358
+ })
359
+
360
+ // Broadcast events to other apps
361
+ slaveBus.emit('dataLoaded', { count: 42, timestamp: Date.now() })
362
+
363
+ // -------------------------------------------------
364
+
365
+ // slave-vue.ts - Vue micro-frontend
366
+ import { createEventBus, getMaxEventBusManager } from '@maxax/x-plugins-mitt'
367
+
368
+ const slaveBus = createEventBus()
369
+ const manager = getMaxEventBusManager()
370
+
371
+ // Register with master
372
+ manager.registerSlaveBus('vueApp', slaveBus)
373
+
374
+ // Listen to all events from React app
375
+ manager.onSlave('reactApp', 'dataLoaded', (data) => {
376
+ console.log('React app loaded data:', data)
377
+ })
378
+
379
+ // Send events to master
380
+ manager.toMaster('vueReady', { name: 'Vue Admin', status: 'active' })
381
+ ```
382
+
383
+ ### Using with React
384
+
385
+ ```typescript
386
+ // useEventBus.ts
387
+ import { useEffect, useCallback } from 'react'
388
+ import { getEventBus } from '@maxax/x-plugins-mitt'
389
+
390
+ export function useEventBus<EventMap extends Record<string, any>>() {
391
+ const eventBus = getEventBus()
392
+
393
+ const subscribe = useCallback(<K extends keyof EventMap>(
394
+ event: K,
395
+ callback: (data: EventMap[K]) => void
396
+ ) => {
397
+ return eventBus.on(event, callback)
398
+ }, [eventBus])
399
+
400
+ const publish = useCallback(<K extends keyof EventMap>(
401
+ event: K,
402
+ data: EventMap[K]
403
+ ) => {
404
+ eventBus.emit(event, data)
405
+ }, [eventBus])
406
+
407
+ return { subscribe, publish }
408
+ }
409
+
410
+ // Component.tsx
411
+ import { useEventBus } from './useEventBus'
412
+
413
+ interface MyEvents {
414
+ counterUpdate: { count: number }
415
+ reset: void
416
+ }
417
+
418
+ function Counter() {
419
+ const { subscribe, publish } = useEventBus<MyEvents>()
420
+ const [count, setCount] = useState(0)
421
+
422
+ useEffect(() => {
423
+ return subscribe('counterUpdate', ({ count }) => {
424
+ setCount(count)
425
+ })
426
+ }, [subscribe])
427
+
428
+ const increment = () => {
429
+ publish('counterUpdate', { count: count + 1 })
430
+ }
431
+
432
+ return <button onClick={increment}>{count}</button>
433
+ }
434
+ ```
435
+
436
+ ### Using with Vue 3 Composable
437
+
438
+ ```typescript
439
+ // composables/useEventBus.ts
440
+ import { onUnmounted } from 'vue'
441
+ import { getEventBus } from '@maxax/x-plugins-mitt'
442
+
443
+ export function useEventBus<EventMap extends Record<string, any>>() {
444
+ const eventBus = getEventBus()
445
+
446
+ const on = <K extends keyof EventMap>(
447
+ event: K,
448
+ callback: (data: EventMap[K]) => void
449
+ ) => {
450
+ const unsubscribe = eventBus.on(event, callback)
451
+ onUnmounted(unsubscribe)
452
+ return unsubscribe
453
+ }
454
+
455
+ const emit = <K extends keyof EventMap>(
456
+ event: K,
457
+ data: EventMap[K]
458
+ ) => {
459
+ eventBus.emit(event, data)
460
+ }
461
+
462
+ return { on, emit }
463
+ }
464
+ ```
465
+
466
+ ## TypeScript Support
467
+
468
+ This library is written in TypeScript and provides full type safety:
469
+
470
+ ```typescript
471
+ import { createEventBus } from '@maxax/x-plugins-mitt'
472
+
473
+ // Define your events
474
+ interface AppEvents {
475
+ userLogin: { userId: string; username: string }
476
+ userLogout: void
477
+ notification: { message: string; type: string }
478
+ [key: string]: any
479
+ }
480
+
481
+ // Create typed event bus
482
+ const eventBus = createEventBus<AppEvents>()
483
+
484
+ // Fully typed events
485
+ eventBus.on('userLogin', (data) => {
486
+ // data is inferred as { userId: string; username: string }
487
+ console.log(data.userId)
488
+ })
489
+
490
+ eventBus.emit('userLogin', { userId: '123', username: 'john' })
491
+ ```
492
+
493
+ ## Performance Tips
494
+
495
+ 1. **Unsubscribe when done**: Always unsubscribe from events when components are destroyed to prevent memory leaks.
496
+
497
+ 2. **Use `once` for one-time events**: For initialization logic that should run only once, use `once()` instead of `on()`.
498
+
499
+ 3. **Manager for cross-app communication**: Use `MaxEventBusManager` for micro-frontend scenarios instead of creating multiple independent event buses.
500
+
501
+ ## Contributing
502
+
503
+ Contributions are welcome! Please read our contributing guidelines before submitting PRs.
504
+
505
+ ## License
506
+
507
+ MIT License - see [LICENSE](LICENSE) for details.