Skip to content

EventBus ​

The EventBus class is the publish/subscribe messaging system used throughout Vio. It provides typed event emission, wildcard listeners, and event history tracking.

Import ​

ts
import { EventBus } from '@atrotos/vio'

TIP

Every VioApp has an internal EventBus. You interact with it via app.on() and app.emit(). The EventBus class is exported for advanced use cases, testing, or building custom modules.

Signature ​

ts
class EventBus {
  constructor(options?: EventBusOptions)
  on(type: string, handler: EventHandler): () => void
  emit(type: string, payload?: Record<string, unknown>): void
  getHistory(): VioEvent[]
  clear(): void
}

Constructor ​

ts
new EventBus(options?: EventBusOptions)

EventBusOptions ​

ts
interface EventBusOptions {
  historySize?: number
}
PropertyTypeDefaultDescription
historySizenumber100Maximum number of events to retain in history. Set to 0 to disable history.
ts
const bus = new EventBus({ historySize: 50 })

Methods ​

on(type, handler) ​

Subscribes a handler to events of the given type. Returns an unsubscribe function.

ts
on(type: string, handler: (event: VioEvent) => void): () => void
ParameterTypeDescription
typestringEvent type to listen for. Use '*' to listen to all events.
handler(event: VioEvent) => voidCallback invoked with the event object

The handler receives a VioEvent object.

ts
// Listen to a specific event
const unsubscribe = bus.on('store:change', (event) => {
  console.log('Store changed:', event.payload)
})

// Later, stop listening
unsubscribe()

Wildcard Listener ​

Use '*' to receive every event emitted on the bus:

ts
bus.on('*', (event) => {
  console.log(`[${event.type}]`, event.payload)
})

TIP

Wildcard handlers are called in addition to type-specific handlers, not instead of them. They do not receive events that are themselves emitted with the type '*'.

emit(type, payload?) ​

Emits an event to all handlers registered for the given type, plus any wildcard ('*') handlers. The event is also added to the history buffer.

ts
emit(type: string, payload?: Record<string, unknown>): void
ParameterTypeDefaultDescription
typestring--Event type
payloadRecord<string, unknown>{}Event data
ts
bus.emit('user:click', { target: 'submit-button' })

The emitted event object has this shape:

ts
{
  type: 'user:click',
  payload: { target: 'submit-button' },
  timestamp: 1709000000000 // Date.now()
}

getHistory() ​

Returns a copy of the event history array, ordered from oldest to newest.

ts
getHistory(): VioEvent[]
ts
const history = bus.getHistory()
console.log(`${history.length} events recorded`)
history.forEach((e) => {
  console.log(`[${e.timestamp}] ${e.type}`, e.payload)
})

TIP

History size is bounded by the historySize option (default 100). When the limit is exceeded, the oldest events are dropped.

clear() ​

Removes all registered listeners and clears the event history.

ts
clear(): void
ts
bus.clear()
// All listeners removed, history emptied

Built-in Event Types ​

Vio's core modules emit these events automatically:

Event TypeSourcePayload
state:changeRenderer{ instanceId, key, value, prev }
store:changeStore{ action, payload, prev, next }
component:mountRenderer{ instanceId, name }
component:updateRenderer{ instanceId, name }
component:unmountRenderer{ instanceId, name }
route:beforeRouter{ from, to }
route:changeRouter{ from, to, params }
route:afterRouter{ path, params }
batch:startApp{ operations }
batch:endApp{ operations }

You can also emit and listen for any custom event type.

Full Example ​

ts
import { EventBus } from '@atrotos/vio'

const bus = new EventBus({ historySize: 200 })

// Type-specific listener
bus.on('user:login', (event) => {
  console.log('User logged in:', event.payload.username)
})

// Wildcard listener for debugging
const stopLogging = bus.on('*', (event) => {
  console.log(`[${event.type}] at ${event.timestamp}`, event.payload)
})

// Emit events
bus.emit('user:login', { username: 'alice' })
bus.emit('user:action', { action: 'navigate', to: '/dashboard' })

// Check history
const history = bus.getHistory()
console.log(`Total events: ${history.length}`) // 2

// Cleanup
stopLogging()
bus.clear()

Released under the MIT License.