Inter-Widget Events & Reactivity

How widgets talk to each other, refresh themselves, cache data, and report render failures.

MeghaOS widgets aren't islands. They communicate through a shared event bus, poll the backend on their own schedule, cache data for offline use, and report rendering problems back to the agent. This is what makes a generated dashboard feel like a coordinated app rather than a pile of cards.

The event bus

is a lightweight pub/sub channel any widget can fire into or listen on β€” enabling inter-widget reactions without a backend round-trip.

dart
EventBus.instance.fire('timer.complete', { 'id': 'pomodoro-1' });
EventBus.instance.on('timer.complete').listen((data) { /* react */ });

Standard events:

EventMeaning
timer.completeA timer or countdown finished
pomodoro.breakA Pomodoro break started
widget.refreshRequest all widgets to refresh
theme.changedThe theme was changed

This lets, say, a Pomodoro widget dim a focus dashboard when a break begins, or a "refresh all" button update every live card at once.

Reactive data binding (data_bound)

The data_bound widget polls a backend endpoint on an interval and renders the result β€” no JIT code, no manual refresh:

json
{ "type": "data_bound", "dataSource": "/api/system/metrics", "refreshMs": 5000, "display": "metric", "label": "CPU" }
PropPurpose
dataSourceBackend path to poll
refreshMsPoll interval (default 5000)
displaytext Β· metric Β· json Β· chart
labelCaption

Point it at any API endpoint β€” system metrics, a widget data route, or a custom one β€” for a self-updating readout.

Pipelines

The pipeline widget chains reactive stages β€” fetch β†’ transform β†’ filter β†’ count / extract β€” so you can compose a small data flow declaratively (fetch JSON, pull a field, filter rows, show a count) and have it refresh as a unit.

Offline cache

Tier 2 widgets fetch through, an in-memory HTTP cache with per-endpoint TTL. When the network is unavailable, widgets fall back to the last cached response β€” so a weather or stock card still shows its last known value offline instead of erroring.

Persistent widget state

Tier 3 widgets read/write through, which wraps the /api/store/{key} endpoints with in-memory caching to avoid redundant network calls on rebuilds. This is the client half of persistent widgets.

Render telemetry & self-correction

tracks A2UI render failures so they're observable in production, not just in debug logs. Two sources feed it:

  1. The per-component try/catch in a2ui_renderer.dart (caught build errors)
  2. The layout validator rejecting malformed subtrees

Telemetry is posted to /api/ui_telemetry and can be fed back to the agent so it learns to avoid component shapes that don't render β€” a feedback loop that improves generated UIs over time.

Putting it together