Documentation Index
Fetch the complete documentation index at: https://abxbus.archivebox.io/llms.txt
Use this file to discover all available pages before exploring further.
Handler return values are captured in EventResult records and can be consumed as a single value or aggregated across handlers.
Repository example files:
Typed return values
Use the event result type to enforce return typing across handlers.
Python
TypeScript
Rust
Go
from abxbus import BaseEvent, EventBus
class DoMathEvent(BaseEvent[int]):
a: int
b: int
def add(event: DoMathEvent) -> int:
return event.a + event.b
bus = EventBus('AppBus')
bus.on(DoMathEvent, add)
event = await bus.emit(DoMathEvent(a=2, b=3)).now()
result = await event.event_result()
import { BaseEvent, EventBus } from 'abxbus'
import { z } from 'zod'
const DoMathEvent = BaseEvent.extend('DoMathEvent', {
a: z.number(),
b: z.number(),
event_result_type: z.number(),
})
const bus = new EventBus('AppBus')
bus.on(DoMathEvent, (event) => event.a + event.b)
const event = bus.emit(DoMathEvent({ a: 2, b: 3 }))
await event.now()
const result = await event.eventResult()
use abxbus_rust::{
event,
event_bus::EventBus,
BaseEvent,
};
use futures::executor::block_on;
event! {
struct DoMathEvent {
a: i64,
b: i64,
event_result_type: i64,
}
}
let bus = EventBus::new(Some("AppBus".to_string()));
bus.on(DoMathEvent, |event: DoMathEvent| async move {
Ok(event.a + event.b)
});
let event = bus.emit(DoMathEvent { a: 2, b: 3, ..Default::default() });
let result = block_on(event.event_result())?;
type DoMathPayload struct {
A int `json:"a"`
B int `json:"b"`
}
bus := abxbus.NewEventBus("AppBus", nil)
abxbus.OnTyped[DoMathPayload, int](
bus,
"DoMathEvent",
"add",
func(payload DoMathPayload) (int, error) {
return payload.A + payload.B, nil
},
nil,
)
event, err := abxbus.NewBaseEventWithResult[DoMathPayload, int](
"DoMathEvent",
DoMathPayload{A: 2, B: 3},
)
if err != nil {
panic(err)
}
emitted := bus.Emit(event)
result, err := emitted.EventResult()
Aggregating multiple handler results
When multiple handlers respond to the same event, collect all successful values with the list helpers.
Python
TypeScript
Rust
Go
event = await bus.emit(GetConfigEvent()).now()
values = await event.event_results_list(raise_if_any=False, raise_if_none=False)
const event = bus.emit(GetConfigEvent({}))
const values = await event.eventResultsList({ raise_if_any: false, raise_if_none: false })
use abxbus_rust::{
base_event::EventResultOptions,
event,
event_bus::EventBus,
BaseEvent,
};
use futures::executor::block_on;
use serde_json::json;
event! {
struct GetConfigEvent {
event_result_type: serde_json::Value,
}
}
let bus = EventBus::new(Some("ConfigBus".to_string()));
bus.on(GetConfigEvent, |_event: GetConfigEvent| async move {
Ok(json!({"debug": true, "port": 8080}))
});
bus.on(GetConfigEvent, |_event: GetConfigEvent| async move {
Ok(json!({"debug": false, "timeout": 30}))
});
let event = bus.emit(GetConfigEvent { ..Default::default() });
let values = block_on(event.event_results_list_with_options(EventResultOptions {
raise_if_any: false,
raise_if_none: false,
..EventResultOptions::default()
}))?;
event := bus.Emit(abxbus.NewBaseEvent("GetConfigEvent", nil))
values, err := event.EventResultsList(
&abxbus.EventResultOptions{RaiseIfAny: false, RaiseIfNone: false},
)
Result list options
Python
TypeScript
Rust
Go
await event.event_results_list(raise_if_any=False, raise_if_none=False)
await event.event_results_list(include=lambda result, _: isinstance(result, dict), raise_if_any=False)
completed = await event.wait(timeout=0.25)
await completed.event_results_list()
await event.eventResultsList({ raise_if_any: false, raise_if_none: false })
await event.eventResultsList({ include: (result) => typeof result === 'object', raise_if_any: false })
await event.wait({ timeout: 0.25 }).eventResultsList()
use abxbus_rust::base_event::{EventResultOptions, EventWaitOptions};
event.event_results_list_with_options(EventResultOptions {
raise_if_any: false,
raise_if_none: false,
..EventResultOptions::default()
}).await?;
let completed = event.wait_with_options(EventWaitOptions {
timeout: Some(0.25),
..EventWaitOptions::default()
}).await?;
completed.event_results_list().await?;
event.EventResultsList(&abxbus.EventResultOptions{
RaiseIfAny: false,
RaiseIfNone: false,
})
timeout := 0.25
completed, err := event.Wait(&abxbus.EventWaitOptions{Timeout: &timeout})
if err != nil {
return err
}
completed.EventResultsList()
- Default options are
raise_if_any=true and raise_if_none=false in every runtime.
raise_if_any: raise if any handler ended with an error.
raise_if_none: raise only when no handlers returned a valid value after filtering; it does not raise just because one handler returned None/null/undefined.
- If every handler errors, only
raise_if_any=false plus raise_if_none=false suppresses the error and returns no value/empty list; every other option combination raises.
- A single handler error is raised as that error; multiple handler errors are raised as an aggregate/exception-group shape.
- Default filtering includes only completed, successful, non-empty scalar/object/list values and excludes forwarded
BaseEvent returns.
- Go accepts no args for defaults (
event.EventResult() / event.EventResultsList()) and a single nil options value is equivalent to defaults.
Per-handler inspection
All runtimes keep per-handler result metadata in addition to the aggregate result helpers.
Python
TypeScript
Rust
Go
by_name = {result.handler_name: result.result for result in event.event_results.values()}
const byHandler = event.event_results
let by_name: std::collections::HashMap<_, _> = event
.event_results
.read()
.values()
.map(|result| (result.handler.handler_name.clone(), result.result.clone()))
.collect();
byName := map[string]any{}
for _, result := range event.EventResults {
byName[result.HandlerName] = result.Result
}