Skip to main content

Events and subscriptions

React to state changes with the event system and subscribables.

Events tell you what happened. Subscribables tell you what state looks like now. Use events to react to discrete actions, use subscribables to keep your UI in sync.

Live event stream

  • No events yet.

Events

Register a listener with engine.on(). It returns an unsubscribe function:

ts
const unsub = engine.on('node:created', (node) => {
  console.log('Created', node.id)
})

// Later...
unsub()

Event catalog

Subscribables

Six subscribables give you reactive access to engine state. Each fires independently — a camera change does not trigger a $nodes notification:

ts
engine.$nodes.subscribe((nodes) => {
  console.log('Node count:', nodes.size)
})

Fires when any node is created, updated, moved, resized, or deleted.

In Vue, prefer the composables (useBoardCamera(), useBoardNodes(), useBoardSelection()) over raw subscribables. They handle reactivity automatically.
Inside engine.batch(), entity events and subscribable notifications publish only after the outer batch commits. Command lifecycle events describe the outer batch boundary. A blocked command and a validation failure remain observable failure telemetry.

Error taxonomy

  • BoardInputError: malformed or invalid boundary input.
  • BoardNotFoundError: requested entity does not exist.
  • BoardConflictError: an ID, plugin name, or other unique identity conflicts.
  • CommandBlockedError: a command guard rejected the operation.
  • BoardDestroyedError: a command targeted a destroyed engine.

Listener, subscriber, and finalized commit-effect errors are reported through onUnhandledError after commit. They do not reverse committed state.