How do I emit events?
Basic usage
import { AppEventBus } from '../../../core/index.js';
AppEventBus.emit('language-changed', { lang: 'fr' });
emit(event, data) is fire-and-forget and synchronous — it calls every current subscriber immediately, in registration order, and returns void. There's no queuing or async dispatch, so a subscriber added after emit() runs won't see that call. A subscriber that throws is logged with console.error, and the other subscribers still run. See How do I listen to application events? for subscribing.
Typed payloads via Nutin.EventMap
Events and their payloads are typed via Nutin.EventMap, built from the framework's own Nutin.FrameworkEventMap (Nutin.RouterEventMap, Nutin.LifecycleEventMap and Nutin.I18nEventMap) plus a Nutin.AppEventMap your app extends via TypeScript declaration merging (namespaces and interfaces merge across files):
// src/app/globals.d.ts
declare namespace Nutin {
interface AppEventMap {
'task-saved': { taskId: number };
'tasks-cleared': undefined;
}
}
This merge is purely a compile-time typing mechanism: Nutin.AppEventMap / Nutin.EventMap are type-only declarations in the global Nutin namespace, not exported values, so there's nothing to import. The underlying event bus isn't restricted to statically known keys at runtime; the declaration only adds type safety on top of it.
AppEventBus.emit('task-saved', { taskId: 3 }); // payload required and type-checked
AppEventBus.emit('tasks-cleared'); // declared `undefined`: no payload
AppEventBus.emit('task-saved'); // type error: payload missing
AppEventBus.emit('unknown-event'); // type error: not in Nutin.EventMap
Declare an event without payload as undefined (not {}), so emit() can be called without one. The framework's own payload-less events (reload, before-render, after-render, before-destroy, after-destroy) are declared that way.
See What are events in Nutin? for how this fits alongside DOM events and the Lifecycle/Navigation facades.