forceCalendar
Interface Package

EventBus

Cross-component event communication with wildcards, priority, and one-time subscriptions.

Overview

EventBus provides a publish/subscribe system for communication between forceCalendar components. It supports wildcard patterns, priority-based handler ordering, and one-time subscriptions.

A singleton instance (eventBus) is shared across all components.

import { eventBus, EventBus } from '@forcecalendar/interface';

// Use the singleton
eventBus.on('navigation:*', (data) => {
  console.log('Navigation event:', data);
});

// Or create a new instance
const bus = new EventBus();

Subscribing

on(eventName, handler, options?)

Subscribe to an event. Returns void.

eventBus.on('event:added', (data) => {
  console.log('Event added:', data);
});

// With options
eventBus.on('event:added', handler, {
  priority: 10,  // Higher priority = called first (default: 0)
});

once(eventName, handler, options?)

Subscribe to an event for a single invocation. The handler is automatically removed after it fires once.

eventBus.once('calendar:ready', (data) => {
  console.log('Calendar initialized');
});

Wildcard Patterns

Event names use colon-separated namespaces. Wildcards match any segment:

// Match all navigation events
eventBus.on('navigation:*', handler);
// Matches: navigation:next, navigation:previous, navigation:today

// Match all events in any namespace
eventBus.on('*', handler);
// Matches everything

Pattern Matching Rules

PatternMatchesDoes Not Match
event:addedevent:added onlyevent:updated, event:*
event:*event:added, event:updated, event:removednavigation:next
*Everything

Wildcard handlers are stored separately from exact-match handlers. When an event fires, both the exact-match handlers and any matching wildcard handlers are invoked.

Emitting

emit(eventName, data?)

Emit an event to all matching subscribers.

eventBus.emit('navigation:next', { date: new Date(), view: 'month' });

Handler invocation order:

  1. Exact-match handlers, sorted by priority (highest first)
  2. Wildcard handlers, sorted by priority (highest first)

Unsubscribing

off(eventName, handler)

Remove a specific handler for an event.

eventBus.off('event:added', myHandler);

offWildcard(pattern, handler)

Remove a specific wildcard handler.

eventBus.offWildcard('navigation:*', myHandler);

offAll(eventName)

Remove all handlers for an event.

eventBus.offAll('event:added');

clear()

Remove all handlers for all events.

eventBus.clear();

Introspection

MethodReturnsDescription
getEventNames()string[]All registered event names
getHandlerCount(eventName)numberNumber of handlers for an event
getWildcardHandlerCount(pattern)numberNumber of wildcard handlers
getTotalHandlerCount()numberTotal handlers across all events

Internal Event Names

These events are used internally by forceCalendar components:

EventEmitted ByData
navigation:nextForceCalendar{ date, view }
navigation:previousForceCalendar{ date, view }
navigation:todayForceCalendar{ date, view }
view:changeForceCalendar{ view }
event:addedForceCalendar{ event }
event:updatedForceCalendar{ event }
event:removedForceCalendar{ eventId }
date:selectMonthViewRenderer{ date }
event:selectRenderers{ eventId }

Priority Example

// Low priority - runs last
eventBus.on('event:added', (data) => {
  logToAnalytics(data);
}, { priority: -10 });

// Default priority (0)
eventBus.on('event:added', (data) => {
  updateUI(data);
});

// High priority - runs first
eventBus.on('event:added', (data) => {
  validateEvent(data);
}, { priority: 10 });