Types
MFEEventBus
Bus eventi globale per comunicazione cross-MFE. API minimale emit/on/off con payload typed.
Contratto
interface MFEEventBus {
emit(eventName: string, payload?: unknown): void
on(eventName: string, handler: (payload?: unknown) => void): void
off(eventName: string, handler: (payload?: unknown) => void): void
}
Quando usarlo
L'EventBus è il canale di comunicazione fire-and-forget tra MFE. Tipico per:
- notifiche di stato (
'user-logged-out','theme-changed') - broadcast di eventi business (
'cliente-creato','ordine-confermato') - refresh coordinato (
'data-invalidated'→ ogni MFE ricarica le proprie liste)
Non usare per:
- richieste request/response (usa
ctx.httpo uno store condiviso) - dati persistenti (usa API server-side)
- accoppiamento stretto tra MFE (introduce dipendenze nascoste)
Pattern d'uso
Publish
import { useMfeContext } from '@pzeta/mfe-contracts/composables'
const ctx = useMfeContext()
async function creaCliente(data: CreateClienteRequest) {
const cliente = await ctx.http.post<Cliente>('/api/clienti', data)
ctx.eventBus?.emit('cliente-creato', cliente.data)
}
Subscribe
import { onMounted, onBeforeUnmount } from 'vue'
import { useMfeContext } from '@pzeta/mfe-contracts/composables'
const ctx = useMfeContext()
function onClienteCreato(payload: unknown) {
const cliente = payload as Cliente
// ricarica lista clienti
}
onMounted(() => {
ctx.eventBus?.on('cliente-creato', onClienteCreato)
})
onBeforeUnmount(() => {
ctx.eventBus?.off('cliente-creato', onClienteCreato)
})
Ricordati sempre
off() in onBeforeUnmount. I listener orfani causano memory leak e bug di "doppia esecuzione" dopo unmount/remount del MFE.Tipizzare il payload
La signature unknown è intenzionale per disaccoppiare i MFE. Per ottenere type safety, definisci un registro eventi condiviso in un pacchetto comune:
// @pzeta/shell-events (pacchetto condiviso shell + MFE)
export interface ShellEvents {
'cliente-creato': Cliente
'cliente-eliminato': { id: string }
'user-logged-out': void
}
// Wrapper tipizzato nel MFE
import type { ShellEvents } from '@pzeta/shell-events'
function emit<K extends keyof ShellEvents>(name: K, payload: ShellEvents[K]) {
ctx.eventBus?.emit(name, payload)
}
function on<K extends keyof ShellEvents>(
name: K,
handler: (payload: ShellEvents[K]) => void,
) {
ctx.eventBus?.on(name, handler as (p?: unknown) => void)
}
Implementazione lato shell
La shell deve fornire un'implementazione concreta di MFEEventBus. Esempio minimale basato su EventTarget:
class ShellEventBus implements MFEEventBus {
private readonly target = new EventTarget()
private readonly wrappers = new Map<
(payload?: unknown) => void,
EventListener
>()
emit(eventName: string, payload?: unknown): void {
this.target.dispatchEvent(new CustomEvent(eventName, { detail: payload }))
}
on(eventName: string, handler: (payload?: unknown) => void): void {
const wrapper: EventListener = (ev) =>
handler((ev as CustomEvent).detail)
this.wrappers.set(handler, wrapper)
this.target.addEventListener(eventName, wrapper)
}
off(eventName: string, handler: (payload?: unknown) => void): void {
const wrapper = this.wrappers.get(handler)
if (wrapper) {
this.target.removeEventListener(eventName, wrapper)
this.wrappers.delete(handler)
}
}
}
In alternativa: mitt, nanoevents, RxJS Subject, o store globale Pinia.
Tipi correlati
MFEContext.eventBus— accesso dal MFE