Skip to content

Channel & events

OmegaChannel is the shared event bus: any part of the app can emit(OmegaEvent) and listen to channel.events. Flows and agents subscribe here; the UI typically sends intents through the OmegaFlowManager or emits events for cross-cutting updates.


Minimal usage

dart
final channel = OmegaChannel();
channel.emit(OmegaEvent.fromName(AppEvent.authLoginRequest, payload: creds));
// Or: OmegaEvent.fromName<MyDto>(AppEvent.someCase, payload: dto) — generic matches payload type.
channel.events.listen((e) {
  // e.payloadAs<MyDto>() or e.typedPayloadAs<MyTypedEvent>() when payload implements OmegaTypedEvent
});
// When the app shuts down:
// channel.dispose();

Always dispose() the channel when the owning scope tears down (same lifetime as your MaterialApp / process).


Typed names

Prefer OmegaEvent.fromName / OmegaIntent.fromName (static methods on the classes) with enums implementing OmegaEventName / OmegaIntentName (see AppEvent / AppIntent in example/lib/omega/app_semantics.dart). That keeps wire strings in one place and survives refactors.

Use payloadAs<T>() on OmegaEvent / OmegaIntent for safe casts. Use typedPayloadAs<T>() on events when T implements OmegaTypedEvent (usually after emitTyped), and on intents when T implements OmegaTypedIntent (usually after handleTypedIntent).


Typed payloads (analyzer-checked)

  • OmegaEvent.fromName<T>(enumCase, payload: …) / OmegaIntent.fromName<T>(enumCase, payload: …) — the type parameter T must match the payload you pass (plain DTOs in example/lib/auth/auth_events.dart).
  • Bus: OmegaTypedEvent + emitTyped — one class carries name + fields; listeners use typedPayloadAs or payloadAs.
  • UI → flow: OmegaTypedIntent + flowManager.handleTypedIntent(myIntent) — the same object is the wire (implements OmegaIntentName) and the OmegaIntent.payload. In onIntent, read ctx.intent?.typedPayloadAs<MyIntent>() (see AuthLoginIntent / AuthLogoutIntent in the example).

Namespaces

For large apps, channel.namespace('orders') returns an OmegaChannelNamespace (bus view) so module traffic stays grouped. Flows and agents can take a namespace instead of the root channel — the example wires auth, provider, and orders.


Typed events on the bus

OmegaTypedEvent + emitTyped give stronger typing for bus events when you need it. For intents, either a plain DTO with OmegaIntent.fromName<Dto>(…) or a single class implements OmegaTypedIntent with handleTypedIntent (example auth).


OmegaEventBus abstraction

OmegaFlow and OmegaAgent accept an OmegaEventBus — either the root channel or a namespace — so the same code works scoped or global.


Debugging


Full examples

Study example/lib/auth/ (login request / success / error events) alongside example/lib/omega/omega_setup.dart for namespace wiring.


Next