Application events guide

A TypeScript event bus for loosely coupled modules

Use a small synchronous event bus when application modules need to exchange intent without importing or calling one another directly. White Label Mediator keeps event ownership explicit.

Publish intent without coupling modules

A publisher dispatches a named event without knowing which module will react. Subscribers own their reactions and can be added or removed without changing the publisher.

White Label Mediator extends the native EventTarget contract and carries application payloads in CustomEvent.detail in browser and supported Node.js environments.

import Mediator from 'white-label-mediator';

const mediator = new Mediator();
mediator.addEventListener('menu:state', event => console.log(event.detail.open));
mediator.dispatchEvent(new CustomEvent('menu:state', {detail: {open: true}}));

Add typed events when the application has a vocabulary

An optional TypeScript event map constrains addEventListener() event names and narrows CustomEvent.detail for typed listener callbacks without adding runtime validation or framework semantics.

dispatchEvent() remains the native EventTarget method, so applications still construct CustomEvent payloads explicitly; the package does not runtime-validate publication payloads.

type Events = {
    ready: string;
};

const mediator = new Mediator<Events>();
mediator.addEventListener('ready', event => console.log(event.detail.toUpperCase()));
mediator.dispatchEvent(new CustomEvent('ready', {detail: 'Ada'}));

Keep listener ownership explicit

The component that subscribes should keep the callback reference and remove its own listener with removeEventListener() during teardown. destroy() is for the mediator itself leaving the application and removes listeners owned by that instance.

Delivery is synchronous: after dispatchEvent() returns, the current listeners have already run. Its boolean return value follows native EventTarget cancellation semantics; it does not report whether any listener received the event.

Use an event bus for cross-module intent, not everything

An event bus is useful when independent modules genuinely need to communicate without a direct dependency. Direct function calls are often clearer when the caller already owns the callee and no decoupling boundary is needed.

Keeping that distinction visible prevents the event bus from becoming an implicit global application API.