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.