Horizon Framework

Event Bus

An Event Bus is provided as a way to communicate between Platform Components. This allows the components to be completely decoupled and enables seamless communication.

| Note: The Event Bus relies on all components being loaded at the same time. If your component is loaded later it will not receive events that have already been emitted. |

type EventType =
  | { topic: 'my-event'; payload: number }
  | { topic: 'another-event'; payload: string }

import { globalEventBus } from '@skedulo/horizon-core'

globalEventBus.addListener((event) => {
  switch (event.topic) {
    case 'my-event':
      console.log(event.payload)
      break
  }
})
globalEventBus.emit({ topic: 'my-event', payload: 123 })

// React
import { useEventBus } from '@skedulo/horizon-core'

const MyComponent = () => {
  const eventbus = useEventBus<EventType>((event) => {
    switch (event.topic) {
      case 'my-event':
        console.log(event.payload)
        break
    }
  })

  const handleClick = () => {
    eventbus.emit({ topic: 'another-event', payload: 'something' })
  }

  return <button onClick={handleClick}>Click me</button>
}

Event Bus Scope

The Event Bus can be scoped so that child Platform Components only listen to sibling events - for example if you wanted to include two list views on a page and you don't want them to accidentally interact with each other. The scope components can also optionally buffer events so that anything emitted before all children are loaded will still be delivered, meaning it's not necessary to keep track of whether components are ready to receive events.

If the closed attribute of platform-eventbus-scope is set child events are only emitted to their siblings and the global eventbus - parents are skipped.

// React
import { EventBusScope } from '@skedulo/horizon-core'

const MyComponent = () => (
  <>
    <EventBusScope>
      <PlatformComponent packageName="pkg" name="DataLoader" id="1" />
      <PlatformComponent packageName="pkg" name="DataViewer" />
    </EventBusScope>
    <EventBusScope>
      <PlatformComponent packageName="pkg" name="DataLoader" id="2" />
      <PlatformComponent packageName="pkg" name="DataViewer" />
    </EventBusScope>
  </>
)

// Platform Templates
const render = () => html`
  <platform-eventbus-scope>
    <platform-component
      package-name="pkg"
      name="DataLoader"
      id="1"
    ></platform-component>
    <platform-component
      package-name="pkg"
      name="DataViewer"
    ></platform-component>
  </platform-eventbus-scope>
  <platform-eventbus-scope>
    <platform-component
      package-name="pkg"
      name="DataLoader"
      id="2"
    ></platform-component>
    <platform-component
      package-name="pkg"
      name="DataViewer"
    ></platform-component>
  </platform-eventbus-scope>
`