Skip to main content
BaseEvent is the typed payload + runtime state object that flows through the bus. Use subclassing (Python) or BaseEvent.extend(...) (TypeScript) to define event payload fields.

Defining events

Queue semantics are split in each runtime:
  • Immediate path: await event.now() (Python/TypeScript), event.Now() (Go), event.now().await (Rust)
  • Queue-order path: await event.wait() (Python/TypeScript), event.Wait() (Go), event.wait().await (Rust)
now() and wait() accept the wait-shaping options (first_result and timeout). Result filtering and error policy live on event_result() / event_results_list(). Python also supports await event as a Python-only shortcut for await event.now(). Other runtimes require the explicit now() / wait() methods. In Go the same split is exposed as event.Now() for immediate queue-jump execution and event.Wait() for normal queue-order waiting. In Rust the same split is exposed as event.now().await for immediate queue-jump execution and event.wait().await for normal queue-order waiting. Unset event option fields are not hydrated onto the event at emit time; the bus that actually processes the event resolves its defaults at execution time.

Core metadata fields

Common event metadata fields available in all runtimes:
  • event_id: unique UUIDv7
  • event_type: event name/type key
  • event_version: payload version marker
  • event_result_type: expected handler return schema/type
  • event_timeout: per-event timeout override (None/null means use the current processing bus default at execution time; 0 disables)
  • event_handler_timeout: per-handler timeout cap override
  • event_handler_slow_timeout: per-handler slow warning threshold (None/null means use the current processing bus default; 0 disables)
  • event_slow_timeout: per-event slow warning threshold (None/null means use the current processing bus default; 0 disables)
  • event_concurrency: event scheduling mode override (None/null/zero-value mode means use the current processing bus default)
  • event_handler_concurrency: handler scheduling mode override (None/null/zero-value mode means use the current processing bus default)
  • event_handler_completion: handler completion strategy override (None/null/zero-value mode means use the current processing bus default)

Runtime fields

  • event_status: pending/started/completed
  • event_created_at, event_started_at, event_completed_at
  • event_started_at / event_completed_at are None (Python) / null (TypeScript) until set
  • event_parent_id and event_emitted_by_handler_id are None / null when unset
  • event_blocks_parent_completion: True / true only for linked children awaited from the handler that emitted them
  • event_path: buses traversed
  • event_results: per-handler result entries
  • Child-event tracking (event_children/descendants)

Completion model

Events are returned in pending state from emit(), then complete asynchronously.

Result access helpers

Result helpers share the same defaults in all runtimes:
  • raise_if_any=true: raise when any handler result is an error.
  • raise_if_none=false: return None / undefined / nil / [] when no result matches the filter.
  • If every handler errors, only raise_if_any=false plus raise_if_none=false suppresses the error. Any other combination raises.
  • A single handler error is raised as that error; multiple handler errors are raised as an aggregate/exception-group shape.

First Result

All results

Per-handler result entries

You can create/update a specific EventResult entry for a handler (useful for controlled seeding/rehydration flows).

Resetting an event

You can create a fresh pending copy for re-emit.

Serialization

Events are JSON-serializable in all runtimes for bridge and cross-runtime workflows.

Notes

  • Reserved names are validated in all runtimes:
    • runtime API names such as bus, emit, now, and wait cannot be provided as payload fields where they would collide with event methods/properties.
    • Unknown event_* fields are rejected.
    • Known built-in event_* fields (for example event_timeout) can still be intentionally overridden in event definitions.
  • model_* is also reserved:
    • Python: unknown model_* fields are rejected, but valid Pydantic namespace overrides (for example model_config) are allowed.
    • TypeScript: any model_* field is rejected.
  • event_result_type drives handler return validation in all runtimes.
  • Parent-child tracking is automatic for event.emit(...) inside handlers. bus.emit(...) creates a top-level event with no parent link.

Reserved Fields