@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 +507 -0
- package/dist/index.cjs +293 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +168 -0
- package/dist/index.d.ts +168 -0
- package/dist/index.mjs +252 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +40 -0
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
|
+
[](https://www.npmjs.com/package/@maxax/x-plugins-mitt)
|
|
6
|
+
[](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.
|