From 52c0a1d7df8bf55a81c1e854ea36cf8310b3304a Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Wed, 13 May 2026 11:45:24 -0700 Subject: [PATCH 1/5] Make Go event APIs typed by default --- abxbus-go/base_event.go | 8 + abxbus-go/event_bus.go | 61 ++++- abxbus-go/event_handler.go | 148 ++++++++++- abxbus-go/jsonl_bridge.go | 8 +- abxbus-go/tests/base_event_test.go | 232 +++++++++--------- .../tests/comprehensive_patterns_test.go | 76 +++--- .../tests/cross_runtime_roundtrip_test.go | 12 +- abxbus-go/tests/event_handler_first_test.go | 124 +++++----- abxbus-go/tests/event_handler_test.go | 34 +-- abxbus-go/tests/event_result_test.go | 122 ++++----- .../eventbus_cross_runtime_features_test.go | 70 +++--- abxbus-go/tests/eventbus_debounce_test.go | 56 ++--- .../eventbus_dispatch_contextvars_test.go | 20 +- .../tests/eventbus_dispatch_defaults_test.go | 12 +- .../eventbus_dispatch_parent_tracking_test.go | 56 ++--- .../tests/eventbus_error_handling_test.go | 20 +- abxbus-go/tests/eventbus_find_test.go | 200 +++++++++------ abxbus-go/tests/eventbus_forwarding_test.go | 124 +++++----- abxbus-go/tests/eventbus_locking_test.go | 48 ++-- abxbus-go/tests/eventbus_log_tree_test.go | 12 +- abxbus-go/tests/eventbus_on_off_test.go | 16 +- abxbus-go/tests/eventbus_performance_test.go | 34 +-- .../tests/eventbus_serialization_test.go | 38 +-- abxbus-go/tests/eventbus_test.go | 194 +++++++-------- abxbus-go/tests/eventbus_timeout_test.go | 112 ++++----- abxbus-go/tests/lock_manager_test.go | 16 +- abxbus-go/tests/roundtrip_cli/main.go | 2 +- abxbus-go/typed.go | 157 ++---------- docs/api/baseevent.mdx | 6 +- docs/api/eventbus.mdx | 28 +-- docs/api/eventhandler.mdx | 2 +- docs/concurrency/backpressure.mdx | 2 +- docs/concurrency/events-bus-serial.mdx | 8 +- docs/concurrency/events-global-serial.mdx | 8 +- docs/concurrency/events-parallel.mdx | 6 +- docs/concurrency/handler-completion-all.mdx | 6 +- docs/concurrency/handler-completion-first.mdx | 6 +- docs/concurrency/handlers-parallel.mdx | 6 +- docs/concurrency/handlers-serial.mdx | 6 +- docs/concurrency/immediate-execution.mdx | 26 +- docs/concurrency/timeouts.mdx | 2 +- docs/features/async-sync-handlers.mdx | 6 +- docs/features/context-propagation.mdx | 6 +- docs/features/event-debouncing.mdx | 20 +- docs/features/event-history-store.mdx | 2 +- docs/features/event-pattern-matching.mdx | 18 +- docs/features/fifo-processing.mdx | 16 +- docs/features/find-events.mdx | 26 +- docs/features/forwarding-between-buses.mdx | 22 +- docs/features/parent-child-tracking.mdx | 24 +- docs/features/return-value-handling.mdx | 8 +- docs/features/typed-events.mdx | 7 +- docs/further-reading/events-suck.mdx | 12 +- docs/index.mdx | 4 +- docs/integrations/bridge-jsonl.mdx | 4 +- docs/integrations/bridges.mdx | 4 +- docs/quickstart.mdx | 6 +- 57 files changed, 1215 insertions(+), 1094 deletions(-) diff --git a/abxbus-go/base_event.go b/abxbus-go/base_event.go index dda7bd63..a6cfb5eb 100644 --- a/abxbus-go/base_event.go +++ b/abxbus-go/base_event.go @@ -657,6 +657,14 @@ func (e *BaseEvent) Emit(input any) *BaseEvent { return e.EmitWithContext(nil, input) } +func (e *BaseEvent) EmitEventName(event_name string, payload map[string]any) *BaseEvent { + return e.Emit(NewBaseEvent(event_name, payload)) +} + +func (e *BaseEvent) EmitEventNameWithContext(ctx context.Context, event_name string, payload map[string]any) *BaseEvent { + return e.EmitWithContext(ctx, NewBaseEvent(event_name, payload)) +} + func (e *BaseEvent) EmitWithContext(ctx context.Context, input any) *BaseEvent { event, err := baseEventFromAny(input) if err != nil { diff --git a/abxbus-go/event_bus.go b/abxbus-go/event_bus.go index c2045c6b..f9f8ad88 100644 --- a/abxbus-go/event_bus.go +++ b/abxbus-go/event_bus.go @@ -298,7 +298,18 @@ func (b *EventBus) notifyBusHandlersChange(handler *EventHandler, registered boo } } -func (b *EventBus) On(event_pattern string, handler_name string, handler any, options *EventHandler) *EventHandler { +func (b *EventBus) On(event_name string, handler_name string, handler any, options *EventHandler) *EventHandler { + if event_name == "" || event_name == "*" { + panic(`EventBus.On registers typed handlers for one concrete event name; use EventBus.OnEventName for wildcard or raw event-name handlers`) + } + normalizedHandler, err := normalizeTypedEventHandlerCallable(handler) + if err != nil { + panic(err) + } + return b.registerHandler(event_name, handler_name, normalizedHandler, options) +} + +func (b *EventBus) OnEventName(event_pattern string, handler_name string, handler any, options *EventHandler) *EventHandler { if err := b.rejectIfDestroyed("On"); err != nil { panic(err) } @@ -309,6 +320,10 @@ func (b *EventBus) On(event_pattern string, handler_name string, handler any, op if err != nil { panic(err) } + return b.registerHandler(event_pattern, handler_name, normalizedHandler, options) +} + +func (b *EventBus) registerHandler(event_pattern string, handler_name string, normalizedHandler EventHandlerCallable, options *EventHandler) *EventHandler { h := NewEventHandler(b.Name, b.ID, event_pattern, handler_name, normalizedHandler) explicitID := false if options != nil { @@ -406,6 +421,14 @@ func (b *EventBus) Emit(input any) *BaseEvent { return b.EmitWithContext(nil, input) } +func (b *EventBus) EmitEventName(event_name string, payload map[string]any) *BaseEvent { + return b.Emit(NewBaseEvent(event_name, payload)) +} + +func (b *EventBus) EmitEventNameWithContext(ctx context.Context, event_name string, payload map[string]any) *BaseEvent { + return b.EmitWithContext(ctx, NewBaseEvent(event_name, payload)) +} + func (b *EventBus) EmitWithContext(ctx context.Context, input any) *BaseEvent { if err := b.rejectIfDestroyed("Emit"); err != nil { panic(err) @@ -1704,7 +1727,23 @@ func (b *EventBus) eventMatchesEquals(event *BaseEvent, equals map[string]any) b return eventMatchesEquals(event, equals) } -func (b *EventBus) Find(event_pattern string, where func(event *BaseEvent) bool, options *FindOptions) (*BaseEvent, error) { +func (b *EventBus) Find(input any, where any, options *FindOptions) (*BaseEvent, error) { + event, err := baseEventFromAny(input) + if err != nil { + return nil, err + } + matches, err := normalizeTypedFindPredicate(where) + if err != nil { + return nil, err + } + return b.findEventName(event.EventType, matches, options) +} + +func (b *EventBus) FindEventName(event_pattern string, where func(event *BaseEvent) bool, options *FindOptions) (*BaseEvent, error) { + return b.findEventName(event_pattern, where, options) +} + +func (b *EventBus) findEventName(event_pattern string, where func(event *BaseEvent) bool, options *FindOptions) (*BaseEvent, error) { if err := b.rejectIfDestroyed("Find"); err != nil { return nil, err } @@ -1780,7 +1819,23 @@ func (b *EventBus) Find(event_pattern string, where func(event *BaseEvent) bool, } } -func (b *EventBus) Filter(event_pattern string, where func(event *BaseEvent) bool, options *FilterOptions) ([]*BaseEvent, error) { +func (b *EventBus) Filter(input any, where any, options *FilterOptions) ([]*BaseEvent, error) { + event, err := baseEventFromAny(input) + if err != nil { + return nil, err + } + matches, err := normalizeTypedFindPredicate(where) + if err != nil { + return nil, err + } + return b.filterEventName(event.EventType, matches, options) +} + +func (b *EventBus) FilterEventName(event_pattern string, where func(event *BaseEvent) bool, options *FilterOptions) ([]*BaseEvent, error) { + return b.filterEventName(event_pattern, where, options) +} + +func (b *EventBus) filterEventName(event_pattern string, where func(event *BaseEvent) bool, options *FilterOptions) ([]*BaseEvent, error) { if err := b.rejectIfDestroyed("Filter"); err != nil { return nil, err } diff --git a/abxbus-go/event_handler.go b/abxbus-go/event_handler.go index 1c0102dc..52818834 100644 --- a/abxbus-go/event_handler.go +++ b/abxbus-go/event_handler.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" "reflect" + + "github.com/ArchiveBox/abxbus/abxbus-go/v2/jsonschema" ) type EventHandlerCallable func(event *BaseEvent, ctx context.Context) (any, error) @@ -132,27 +134,30 @@ func normalizeEventHandlerCallable(handler any) (EventHandlerCallable, error) { }, nil default: if !value.IsValid() || value.Kind() != reflect.Func || value.IsNil() { - return nil, fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), or the same forms with context.Context as the second argument; got %T", handler) + return nil, unsupportedHandlerSignatureError(handler) } handlerType := value.Type() if handlerType.NumIn() != 1 && handlerType.NumIn() != 2 { - return nil, fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), or the same forms with context.Context as the second argument; got %T", handler) - } - if handlerType.In(0) != baseEventPointerType { - return nil, fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), or the same forms with context.Context as the second argument; got %T", handler) + return nil, unsupportedHandlerSignatureError(handler) } withContext := handlerType.NumIn() == 2 if withContext && handlerType.In(1) != contextInterfaceType { - return nil, fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), or the same forms with context.Context as the second argument; got %T", handler) + return nil, unsupportedHandlerSignatureError(handler) } if handlerType.NumOut() > 2 { - return nil, fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), or the same forms with context.Context as the second argument; got %T", handler) + return nil, unsupportedHandlerSignatureError(handler) } if handlerType.NumOut() == 1 && !handlerType.Out(0).Implements(errorInterfaceType) { - return nil, fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), or the same forms with context.Context as the second argument; got %T", handler) + if handlerType.In(0) == baseEventPointerType { + return nil, unsupportedHandlerSignatureError(handler) + } + return normalizeTypedEventHandlerReflectCallable(value, handlerType), nil } if handlerType.NumOut() == 2 && !handlerType.Out(1).Implements(errorInterfaceType) { - return nil, fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), or the same forms with context.Context as the second argument; got %T", handler) + return nil, unsupportedHandlerSignatureError(handler) + } + if handlerType.In(0) != baseEventPointerType { + return normalizeTypedEventHandlerReflectCallable(value, handlerType), nil } return func(event *BaseEvent, ctx context.Context) (any, error) { args := []reflect.Value{reflect.ValueOf(event)} @@ -178,3 +183,128 @@ func normalizeEventHandlerCallable(handler any) (EventHandlerCallable, error) { }, nil } } + +func normalizeTypedEventHandlerCallable(handler any) (EventHandlerCallable, error) { + value := reflect.ValueOf(handler) + if value.IsValid() && value.Kind() == reflect.Func && value.IsNil() { + return nil, nil + } + if !value.IsValid() || value.Kind() != reflect.Func || value.IsNil() { + return nil, unsupportedHandlerSignatureError(handler) + } + handlerType := value.Type() + if handlerType.NumIn() != 1 && handlerType.NumIn() != 2 { + return nil, unsupportedHandlerSignatureError(handler) + } + if handlerType.In(0) == baseEventPointerType { + return nil, unsupportedHandlerSignatureError(handler) + } + if handlerType.NumIn() == 2 && handlerType.In(1) != contextInterfaceType { + return nil, unsupportedHandlerSignatureError(handler) + } + if handlerType.NumOut() > 2 { + return nil, unsupportedHandlerSignatureError(handler) + } + if handlerType.NumOut() == 2 && !handlerType.Out(1).Implements(errorInterfaceType) { + return nil, unsupportedHandlerSignatureError(handler) + } + return normalizeTypedEventHandlerReflectCallable(value, handlerType), nil +} + +func unsupportedHandlerSignatureError(handler any) error { + return fmt.Errorf("handler must be one of: func(*BaseEvent), func(*BaseEvent) error, func(*BaseEvent) (any, error), a typed payload handler func(TPayload), func(TPayload) error, func(TPayload) TResult, func(TPayload) (TResult, error), or the same forms with context.Context as the second argument; got %T", handler) +} + +func normalizeTypedEventHandlerReflectCallable(value reflect.Value, handlerType reflect.Type) EventHandlerCallable { + payloadType := handlerType.In(0) + payloadSchema := jsonSchemaForType(payloadType) + withContext := handlerType.NumIn() == 2 + return func(event *BaseEvent, ctx context.Context) (any, error) { + if err := jsonschema.Validate(payloadSchema, event.Payload); err != nil { + return nil, fmt.Errorf("EventHandlerPayloadSchemaError: Event payload did not match declared handler payload type: %w", err) + } + payload, err := eventPayloadAsReflectValue(event, payloadType) + if err != nil { + return nil, err + } + args := []reflect.Value{payload} + if withContext { + args = append(args, reflect.ValueOf(ctx)) + } + results := value.Call(args) + switch len(results) { + case 0: + return nil, nil + case 1: + if results[0].Type().Implements(errorInterfaceType) { + if reflectValueIsNil(results[0]) { + return nil, nil + } + return nil, results[0].Interface().(error) + } + return reflectResultInterface(results[0]), nil + default: + var err error + if !reflectValueIsNil(results[1]) { + err = results[1].Interface().(error) + } + return reflectResultInterface(results[0]), err + } + } +} + +func eventPayloadAsReflectValue(event *BaseEvent, payloadType reflect.Type) (reflect.Value, error) { + if event == nil { + return reflect.Value{}, fmt.Errorf("event is nil") + } + data, err := json.Marshal(event.Payload) + if err != nil { + return reflect.Value{}, err + } + payloadPtr := reflect.New(payloadType) + if err := json.Unmarshal(data, payloadPtr.Interface()); err != nil { + return reflect.Value{}, err + } + return payloadPtr.Elem(), nil +} + +func reflectResultInterface(value reflect.Value) any { + if reflectValueIsNil(value) { + return nil + } + return value.Interface() +} + +func normalizeTypedFindPredicate(where any) (func(*BaseEvent) bool, error) { + if where == nil { + return nil, nil + } + if typed, ok := where.(func(*BaseEvent) bool); ok { + return typed, nil + } + value := reflect.ValueOf(where) + if !value.IsValid() || value.Kind() != reflect.Func || value.IsNil() { + return nil, fmt.Errorf("where must be func(*BaseEvent) bool or func(TPayload) bool; got %T", where) + } + predicateType := value.Type() + if predicateType.NumIn() != 1 || predicateType.NumOut() != 1 || predicateType.Out(0).Kind() != reflect.Bool { + return nil, fmt.Errorf("where must be func(*BaseEvent) bool or func(TPayload) bool; got %T", where) + } + if predicateType.In(0) == baseEventPointerType { + return func(event *BaseEvent) bool { + return value.Call([]reflect.Value{reflect.ValueOf(event)})[0].Bool() + }, nil + } + payloadType := predicateType.In(0) + payloadSchema := jsonSchemaForType(payloadType) + return func(event *BaseEvent) bool { + if err := jsonschema.Validate(payloadSchema, event.Payload); err != nil { + return false + } + payload, err := eventPayloadAsReflectValue(event, payloadType) + if err != nil { + return false + } + return value.Call([]reflect.Value{payload})[0].Bool() + }, nil +} diff --git a/abxbus-go/jsonl_bridge.go b/abxbus-go/jsonl_bridge.go index e99df9a1..9387af3e 100644 --- a/abxbus-go/jsonl_bridge.go +++ b/abxbus-go/jsonl_bridge.go @@ -46,9 +46,9 @@ func NewJSONLEventBridge(path string, pollIntervalSeconds float64, name string) } } -func (b *JSONLEventBridge) On(eventPattern string, handlerName string, handler any, options *EventHandler) *EventHandler { +func (b *JSONLEventBridge) OnEventName(eventPattern string, handlerName string, handler any, options *EventHandler) *EventHandler { _ = b.Start() - return b.inboundBus.On(eventPattern, handlerName, handler, options) + return b.inboundBus.OnEventName(eventPattern, handlerName, handler, options) } func (b *JSONLEventBridge) Emit(event *BaseEvent) (*BaseEvent, error) { @@ -73,6 +73,10 @@ func (b *JSONLEventBridge) Emit(event *BaseEvent) (*BaseEvent, error) { return event, nil } +func (b *JSONLEventBridge) EmitEventName(eventName string, payload map[string]any) (*BaseEvent, error) { + return b.Emit(NewBaseEvent(eventName, payload)) +} + func (b *JSONLEventBridge) Dispatch(event *BaseEvent) (*BaseEvent, error) { return b.Emit(event) } diff --git a/abxbus-go/tests/base_event_test.go b/abxbus-go/tests/base_event_test.go index 0a78b4ce..8833a407 100644 --- a/abxbus-go/tests/base_event_test.go +++ b/abxbus-go/tests/base_event_test.go @@ -64,10 +64,10 @@ func TestBaseEventNowInsideHandlerNoArgs(t *testing.T) { }) order := []string{} - bus.On("NowInsideNoArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowInsideNoArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "parent_start") - event.Bus.Emit(abxbus.NewBaseEvent("NowInsideNoArgsSibling", nil)) - child := event.Emit(abxbus.NewBaseEvent("NowInsideNoArgsChild", nil)) + event.Bus.EmitEventName("NowInsideNoArgsSibling", nil) + child := event.EmitEventName("NowInsideNoArgsChild", nil) timeout := 1.0 if _, err := child.Now(&abxbus.EventWaitOptions{Timeout: &timeout}); err != nil { return nil, err @@ -75,16 +75,16 @@ func TestBaseEventNowInsideHandlerNoArgs(t *testing.T) { order = append(order, "parent_end") return nil, nil }, nil) - bus.On("NowInsideNoArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowInsideNoArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "child") return nil, nil }, nil) - bus.On("NowInsideNoArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowInsideNoArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "sibling") return nil, nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("NowInsideNoArgsParent", nil)) + parent := bus.EmitEventName("NowInsideNoArgsParent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -105,26 +105,26 @@ func TestBaseEventNowInsideHandlerWithArgs(t *testing.T) { order := []string{} var child *abxbus.BaseEvent - bus.On("NowInsideArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowInsideArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "parent_start") - event.Bus.Emit(abxbus.NewBaseEvent("NowInsideArgsSibling", nil)) - child = event.Emit(abxbus.NewBaseEvent("NowInsideArgsChild", nil)) + event.Bus.EmitEventName("NowInsideArgsSibling", nil) + child = event.EmitEventName("NowInsideArgsChild", nil) if _, err := child.Now(); err != nil { return nil, err } order = append(order, "parent_end") return nil, nil }, nil) - bus.On("NowInsideArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowInsideArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "child") return nil, errors.New("child failure") }, nil) - bus.On("NowInsideArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowInsideArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "sibling") return nil, nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("NowInsideArgsParent", nil)) + parent := bus.EmitEventName("NowInsideArgsParent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -152,27 +152,27 @@ func TestWaitOutsideHandlerPreservesNormalQueueOrder(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.On("WaitOutsideHandlerBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("WaitOutsideHandlerBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.On("WaitOutsideHandlerTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("WaitOutsideHandlerTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return nil, nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.Emit(abxbus.NewBaseEvent("WaitOutsideHandlerBlockerEvent", nil)) + bus.EmitEventName("WaitOutsideHandlerBlockerEvent", nil) select { case <-blockerStarted: case <-ctx.Done(): t.Fatal("blocker did not start") } - target := bus.Emit(abxbus.NewBaseEvent("WaitOutsideHandlerTargetEvent", nil)) + target := bus.EmitEventName("WaitOutsideHandlerTargetEvent", nil) doneCh := make(chan error, 1) go func() { _, err := target.Wait() @@ -204,21 +204,21 @@ func TestNowOutsideHandlerAllowsNormalParallelProcessing(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.On("NowOutsideHandlerParallelBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowOutsideHandlerParallelBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.On("NowOutsideHandlerParallelTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowOutsideHandlerParallelTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return nil, nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.Emit(abxbus.NewBaseEvent("NowOutsideHandlerParallelBlockerEvent", nil)) + bus.EmitEventName("NowOutsideHandlerParallelBlockerEvent", nil) select { case <-blockerStarted: case <-ctx.Done(): @@ -258,27 +258,27 @@ func TestWaitReturnsEventWithoutForcingQueuedExecution(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.On("WaitPassiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("WaitPassiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.On("WaitPassiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("WaitPassiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return "target", nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.Emit(abxbus.NewBaseEvent("WaitPassiveBlockerEvent", nil)) + bus.EmitEventName("WaitPassiveBlockerEvent", nil) select { case <-blockerStarted: case <-ctx.Done(): t.Fatal("blocker did not start") } - target := bus.Emit(abxbus.NewBaseEvent("WaitPassiveTargetEvent", nil)) + target := bus.EmitEventName("WaitPassiveTargetEvent", nil) waitedEvent := make(chan *abxbus.BaseEvent, 1) waitErr := make(chan error, 1) timeout := 1.0 @@ -312,27 +312,27 @@ func TestNowReturnsEventAndQueueJumpsQueuedExecution(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.On("NowActiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowActiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.On("NowActiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowActiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return "target", nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.Emit(abxbus.NewBaseEvent("NowActiveBlockerEvent", nil)) + bus.EmitEventName("NowActiveBlockerEvent", nil) select { case <-blockerStarted: case <-ctx.Done(): t.Fatal("blocker did not start") } - target := bus.Emit(abxbus.NewBaseEvent("NowActiveTargetEvent", nil)) + target := bus.EmitEventName("NowActiveTargetEvent", nil) processedEvent := make(chan *abxbus.BaseEvent, 1) nowErr := make(chan error, 1) timeout := 1.0 @@ -369,15 +369,15 @@ func TestWaitFirstResultReturnsBeforeEventCompletion(t *testing.T) { EventTimeout: &noTimeout, }) slowFinished := make(chan struct{}) - bus.On("WaitFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("WaitFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "medium", nil }, nil) - bus.On("WaitFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("WaitFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.On("WaitFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("WaitFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(250 * time.Millisecond) close(slowFinished) return "slow", nil @@ -428,11 +428,11 @@ func TestNowFirstResultReturnsBeforeEventCompletion(t *testing.T) { slowFinished := make(chan struct{}) slowCanceled := make(chan struct{}) releaseSlow := make(chan struct{}) - bus.On("NowFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "medium", nil }, nil) - bus.On("NowFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-slowStarted: case <-time.After(time.Second): @@ -441,7 +441,7 @@ func TestNowFirstResultReturnsBeforeEventCompletion(t *testing.T) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.On("NowFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { close(slowStarted) select { case <-releaseSlow: @@ -499,21 +499,21 @@ func TestEventResultStartsNeverStartedEventAndReturnsFirstResult(t *testing.T) { order := []string{} blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.On("EventResultShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.On("EventResultShortcutTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultShortcutTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return "target", nil }, nil) - bus.Emit(abxbus.NewBaseEvent("EventResultShortcutBlockerEvent", nil)) + bus.EmitEventName("EventResultShortcutBlockerEvent", nil) <-blockerStarted - target := bus.Emit(abxbus.NewBaseEvent("EventResultShortcutTargetEvent", nil)) + target := bus.EmitEventName("EventResultShortcutTargetEvent", nil) resultCh := make(chan any, 1) errCh := make(chan error, 1) go func() { @@ -542,25 +542,25 @@ func TestEventResultsListStartsNeverStartedEventAndReturnsAllResults(t *testing. order := []string{} blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.On("EventResultsShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultsShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.On("EventResultsShortcutTargetEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultsShortcutTargetEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "first") return "first", nil }, nil) - bus.On("EventResultsShortcutTargetEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultsShortcutTargetEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "second") return "second", nil }, nil) - bus.Emit(abxbus.NewBaseEvent("EventResultsShortcutBlockerEvent", nil)) + bus.EmitEventName("EventResultsShortcutBlockerEvent", nil) <-blockerStarted - target := bus.Emit(abxbus.NewBaseEvent("EventResultsShortcutTargetEvent", nil)) + target := bus.EmitEventName("EventResultsShortcutTargetEvent", nil) resultsCh := make(chan []any, 1) errCh := make(chan error, 1) go func() { @@ -601,13 +601,13 @@ func TestEventResultHelpersDoNotWaitForStartedEvent(t *testing.T) { }) handlerStarted := make(chan struct{}) releaseHandler := make(chan struct{}) - bus.On("EventResultHelpersStartedEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultHelpersStartedEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { close(handlerStarted) <-releaseHandler return "late", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("EventResultHelpersStartedEvent", nil)) + event := bus.EmitEventName("EventResultHelpersStartedEvent", nil) <-handlerStarted if event.EventStatus != "started" { @@ -669,14 +669,14 @@ func TestNowOnAlreadyExecutingEventWaitsWithoutDuplicateExecution(t *testing.T) started := make(chan struct{}) release := make(chan struct{}) runCount := 0 - bus.On("NowAlreadyExecutingEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowAlreadyExecutingEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { runCount++ close(started) <-release return "done", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("NowAlreadyExecutingEvent", nil)) + event := bus.EmitEventName("NowAlreadyExecutingEvent", nil) <-started nowCh := make(chan *abxbus.BaseEvent, 1) errCh := make(chan error, 1) @@ -717,7 +717,7 @@ func TestNowTimeoutLimitsCallerWaitAndBackgroundProcessingContinues(t *testing.T handlerSawContextCancel := make(chan struct{}, 1) var startOnce sync.Once - bus.On("NowTimeoutCallerWaitEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowTimeoutCallerWaitEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { startOnce.Do(func() { close(started) }) select { case <-ctx.Done(): @@ -729,7 +729,7 @@ func TestNowTimeoutLimitsCallerWaitAndBackgroundProcessingContinues(t *testing.T } }, nil) - event := bus.Emit(abxbus.NewBaseEvent("NowTimeoutCallerWaitEvent", nil)) + event := bus.EmitEventName("NowTimeoutCallerWaitEvent", nil) timeout := 0.01 if _, err := event.Now(&abxbus.EventWaitOptions{Timeout: &timeout}); err == nil { t.Fatal("expected Now(timeout) to time out") @@ -779,12 +779,12 @@ func TestNowWithRapidHandlerChurnDoesNotDuplicateExecution(t *testing.T) { var runCount atomic.Int64 for index := 0; index < totalEvents; index++ { - handler := bus.On("NowRapidHandlerChurnEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.OnEventName("NowRapidHandlerChurnEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { runCount.Add(1) time.Sleep(time.Millisecond) return "done", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("NowRapidHandlerChurnEvent", nil)) + event := bus.EmitEventName("NowRapidHandlerChurnEvent", nil) timeout := 1.0 completed, err := event.Now(&abxbus.EventWaitOptions{Timeout: &timeout}) if err != nil { @@ -812,20 +812,20 @@ func TestEventResultOptionsApplyToCurrentResults(t *testing.T) { EventTimeout: &noTimeout, }) releaseSlow := make(chan struct{}) - bus.On("EventResultOptionsCurrentResultsEvent", "fail", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultOptionsCurrentResultsEvent", "fail", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("option boom") }, nil) - bus.On("EventResultOptionsCurrentResultsEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultOptionsCurrentResultsEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "keep", nil }, nil) - bus.On("EventResultOptionsCurrentResultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventResultOptionsCurrentResultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-releaseSlow return "late", nil }, nil) timeout := 1.0 - event, err := bus.Emit(abxbus.NewBaseEvent("EventResultOptionsCurrentResultsEvent", nil)).Now( + event, err := bus.EmitEventName("EventResultOptionsCurrentResultsEvent", nil).Now( &abxbus.EventWaitOptions{Timeout: &timeout, FirstResult: true}, ) if err != nil { @@ -853,11 +853,11 @@ func TestEventResultOptionsApplyToCurrentResults(t *testing.T) { func TestBaseEventNowOutsideHandlerNoArgs(t *testing.T) { bus := abxbus.NewEventBus("BaseEventNowOutsideNoArgsBus", nil) - bus.On("NowOutsideNoArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowOutsideNoArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("outside failure") }, nil) - event := bus.Emit(abxbus.NewBaseEvent("NowOutsideNoArgsEvent", nil)) + event := bus.EmitEventName("NowOutsideNoArgsEvent", nil) timeout := 1.0 if _, err := event.Now(&abxbus.EventWaitOptions{Timeout: &timeout}); err != nil { t.Fatalf("Now should wait without surfacing handler errors, got %v", err) @@ -872,11 +872,11 @@ func TestBaseEventNowOutsideHandlerNoArgs(t *testing.T) { func TestBaseEventNowOutsideHandlerWithArgs(t *testing.T) { bus := abxbus.NewEventBus("BaseEventNowOutsideArgsBus", nil) - bus.On("NowOutsideArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowOutsideArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("outside suppressed failure") }, nil) - event := bus.Emit(abxbus.NewBaseEvent("NowOutsideArgsEvent", nil)) + event := bus.EmitEventName("NowOutsideArgsEvent", nil) if _, err := event.Now(); err != nil { t.Fatalf("RaiseIfAny=false should only wait for completion, got %v", err) } @@ -910,7 +910,7 @@ func TestBaseEventEventResultUpdateCreatesAndUpdatesTypedHandlerResults(t *testi bus := abxbus.NewEventBus("BaseEventEventResultUpdateBus", nil) event := abxbus.NewBaseEvent("BaseEventEventResultUpdateEvent", nil) event.EventResultType = map[string]any{"type": "string"} - handlerEntry := bus.On("BaseEventEventResultUpdateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerEntry := bus.OnEventName("BaseEventEventResultUpdateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -949,7 +949,7 @@ func TestBaseEventEventResultUpdateStatusOnlyPreservesExistingErrorAndResult(t * bus := abxbus.NewEventBus("BaseEventEventResultUpdateStatusOnlyBus", nil) event := abxbus.NewBaseEvent("BaseEventEventResultUpdateStatusOnlyEvent", nil) event.EventResultType = map[string]any{"type": "string"} - handlerEntry := bus.On("BaseEventEventResultUpdateStatusOnlyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerEntry := bus.OnEventName("BaseEventEventResultUpdateStatusOnlyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -984,7 +984,7 @@ func TestBaseEventEventResultUpdateValidatesDeclaredResultSchema(t *testing.T) { bus := abxbus.NewEventBus("BaseEventEventResultUpdateSchemaBus", nil) event := abxbus.NewBaseEvent("BaseEventEventResultUpdateSchemaEvent", nil) event.EventResultType = map[string]any{"type": "string"} - handlerEntry := bus.On("BaseEventEventResultUpdateSchemaEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerEntry := bus.OnEventName("BaseEventEventResultUpdateSchemaEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -1019,28 +1019,28 @@ func TestWaitWaitsInQueueOrderInsideHandler(t *testing.T) { orderCh <- label } - bus.On("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - bus.Emit(abxbus.NewBaseEvent("Sibling", nil)) + bus.EmitEventName("Sibling", nil) select { case <-siblingStarted: case <-time.After(time.Second): return nil, errors.New("timed out waiting for sibling to start") } - child = e.Emit(abxbus.NewBaseEvent("Child", nil)) + child = e.EmitEventName("Child", nil) if _, err := child.Wait(); err != nil { return nil, err } record("parent_end") return "parent", nil }, nil) - bus.On("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") time.Sleep(time.Millisecond) record("child_end") return "child", nil }, nil) - bus.On("Sibling", "sibling", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Sibling", "sibling", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("sibling_start") siblingStarted <- struct{}{} time.Sleep(time.Millisecond) @@ -1048,7 +1048,7 @@ func TestWaitWaitsInQueueOrderInsideHandler(t *testing.T) { return "sibling", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1092,11 +1092,11 @@ func TestWaitIsPassiveInsideHandlersAndTimesOutForSerialEvents(t *testing.T) { return append([]string{}, order...) } - bus.On("PassiveSerialParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PassiveSerialParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - emitted := e.Emit(abxbus.NewBaseEvent("PassiveSerialEmittedEvent", nil)) - foundSource := e.Emit(abxbus.NewBaseEvent("PassiveSerialFoundEvent", nil)) - found, err := bus.Find("PassiveSerialFoundEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + emitted := e.EmitEventName("PassiveSerialEmittedEvent", nil) + foundSource := e.EmitEventName("PassiveSerialFoundEvent", nil) + found, err := bus.FindEventName("PassiveSerialFoundEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { return nil, err } @@ -1123,16 +1123,16 @@ func TestWaitIsPassiveInsideHandlersAndTimesOutForSerialEvents(t *testing.T) { record("parent_end") return "parent", nil }, nil) - bus.On("PassiveSerialEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PassiveSerialEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("emitted_start") return "emitted", nil }, nil) - bus.On("PassiveSerialFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PassiveSerialFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("found_start") return "found", nil }, nil) - if _, err := bus.Emit(abxbus.NewBaseEvent("PassiveSerialParentEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventName("PassiveSerialParentEvent", nil).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 @@ -1176,10 +1176,10 @@ func TestWaitSerialWaitInsideHandlerTimesOutAndWarnsAboutSlowHandler(t *testing. } defer func() { abxbus.SlowWarningLogger = original }() - bus.On("EventCompletedSerialDeadlockWarningParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventCompletedSerialDeadlockWarningParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - child := e.Emit(abxbus.NewBaseEvent("EventCompletedSerialDeadlockWarningChildEvent", nil)) - found, err := bus.Find("EventCompletedSerialDeadlockWarningChildEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + child := e.EmitEventName("EventCompletedSerialDeadlockWarningChildEvent", nil) + found, err := bus.FindEventName("EventCompletedSerialDeadlockWarningChildEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { return nil, err } @@ -1200,12 +1200,12 @@ func TestWaitSerialWaitInsideHandlerTimesOutAndWarnsAboutSlowHandler(t *testing. record("parent_end") return "parent", nil }, nil) - bus.On("EventCompletedSerialDeadlockWarningChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventCompletedSerialDeadlockWarningChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") return "child", nil }, nil) - if _, err := bus.Emit(abxbus.NewBaseEvent("EventCompletedSerialDeadlockWarningParentEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventName("EventCompletedSerialDeadlockWarningParentEvent", nil).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 @@ -1241,23 +1241,23 @@ func TestDeferredEmitAfterHandlerCompletionIsAccepted(t *testing.T) { } emitted := make(chan struct{}) - bus.On("DeferredEmitAfterCompletionParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("DeferredEmitAfterCompletionParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") go func() { time.Sleep(20 * time.Millisecond) record("deferred_emit") - e.Emit(abxbus.NewBaseEvent("DeferredEmitAfterCompletionChildEvent", nil)) + e.EmitEventName("DeferredEmitAfterCompletionChildEvent", nil) close(emitted) }() record("parent_end") return "parent", nil }, nil) - bus.On("DeferredEmitAfterCompletionChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("DeferredEmitAfterCompletionChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") return "child", nil }, nil) - if _, err := bus.Emit(abxbus.NewBaseEvent("DeferredEmitAfterCompletionParentEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventName("DeferredEmitAfterCompletionParentEvent", nil).Now(); err != nil { t.Fatal(err) } select { @@ -1293,7 +1293,7 @@ func TestWaitWaitsForNormalParallelProcessingInsideHandlers(t *testing.T) { return append([]string{}, order...) } - bus.On("PassiveParallelParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PassiveParallelParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") emittedEvent := abxbus.NewBaseEvent("PassiveParallelEmittedEvent", nil) emittedEvent.EventConcurrency = abxbus.EventConcurrencyParallel @@ -1301,7 +1301,7 @@ func TestWaitWaitsForNormalParallelProcessingInsideHandlers(t *testing.T) { foundEvent := abxbus.NewBaseEvent("PassiveParallelFoundEvent", nil) foundEvent.EventConcurrency = abxbus.EventConcurrencyParallel foundSource := e.Emit(foundEvent) - found, err := bus.Find("PassiveParallelFoundEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + found, err := bus.FindEventName("PassiveParallelFoundEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { return nil, err } @@ -1324,20 +1324,20 @@ func TestWaitWaitsForNormalParallelProcessingInsideHandlers(t *testing.T) { record("parent_end") return "parent", nil }, nil) - bus.On("PassiveParallelEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PassiveParallelEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("emitted_start") time.Sleep(time.Millisecond) record("emitted_end") return "emitted", nil }, nil) - bus.On("PassiveParallelFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PassiveParallelFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("found_start") time.Sleep(time.Millisecond) record("found_end") return "found", nil }, nil) - if _, err := bus.Emit(abxbus.NewBaseEvent("PassiveParallelParentEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventName("PassiveParallelParentEvent", nil).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 @@ -1370,7 +1370,7 @@ func TestAwaitedParallelQueueJumpChildDoesNotPauseLaterParallelChildEvents(t *te return child } - bus.On("ParallelPauseParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ParallelPauseParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "parent_start") if _, err := e.Emit(newChild("awaited")).Now(&abxbus.EventWaitOptions{FirstResult: true}); err != nil { return nil, err @@ -1379,7 +1379,7 @@ func TestAwaitedParallelQueueJumpChildDoesNotPauseLaterParallelChildEvents(t *te e.Emit(newChild("bg")) appendLocked(&mu, &order, "parent_after_bg_emit") - found, err := bus.Find("ParallelPauseObservedEvent", func(event *abxbus.BaseEvent) bool { + found, err := bus.FindEventName("ParallelPauseObservedEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["name"] == "bg" }, &abxbus.FindOptions{Past: true, Future: 0.2}) if err != nil { @@ -1393,21 +1393,21 @@ func TestAwaitedParallelQueueJumpChildDoesNotPauseLaterParallelChildEvents(t *te return nil, nil }, nil) - bus.On("ParallelPauseChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ParallelPauseChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { name, _ := e.Payload["name"].(string) appendLocked(&mu, &order, "child_start_"+name) if name == "bg" { - e.Emit(abxbus.NewBaseEvent("ParallelPauseObservedEvent", map[string]any{"name": "bg"})) + e.EmitEventName("ParallelPauseObservedEvent", map[string]any{"name": "bg"}) } appendLocked(&mu, &order, "child_end_"+name) return name, nil }, nil) - bus.On("ParallelPauseObservedEvent", "observed_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ParallelPauseObservedEvent", "observed_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "observed_seen") return nil, nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("ParallelPauseParentEvent", nil)) + parent := bus.EmitEventName("ParallelPauseParentEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1428,12 +1428,12 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { order := []string{} parallelDone := make(chan struct{}) - bus.On("ParallelNotPausedParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ParallelNotPausedParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "parent_start") parallelEvent := abxbus.NewBaseEvent("ParallelNotPausedParallelEvent", nil) parallelEvent.EventConcurrency = abxbus.EventConcurrencyParallel e.Emit(parallelEvent) - child := e.Emit(abxbus.NewBaseEvent("ParallelNotPausedChildEvent", nil)) + child := e.EmitEventName("ParallelNotPausedChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } @@ -1441,7 +1441,7 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { return nil, nil }, nil) - bus.On("ParallelNotPausedParallelEvent", "parallel_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ParallelNotPausedParallelEvent", "parallel_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "parallel_start") time.Sleep(5 * time.Millisecond) appendLocked(&mu, &order, "parallel_end") @@ -1449,7 +1449,7 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { return nil, nil }, nil) - bus.On("ParallelNotPausedChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ParallelNotPausedChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "child_start") select { case <-parallelDone: @@ -1461,7 +1461,7 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { return nil, nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("ParallelNotPausedParentEvent", nil)) + parent := bus.EmitEventName("ParallelNotPausedParentEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1489,10 +1489,10 @@ func TestWaitWaitsForFutureParallelEventFoundAfterHandlerStarts(t *testing.T) { continued := make(chan struct{}) waitedFor := make(chan time.Duration, 1) - bus.On("FutureParallelSomeOtherEvent", "other", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("FutureParallelSomeOtherEvent", "other", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { close(otherStarted) <-releaseFind - found, err := bus.Find("FutureParallelEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + found, err := bus.FindEventName("FutureParallelEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { return nil, err } @@ -1508,13 +1508,13 @@ func TestWaitWaitsForFutureParallelEventFoundAfterHandlerStarts(t *testing.T) { close(continued) return "other", nil }, nil) - bus.On("FutureParallelEvent", "parallel", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("FutureParallelEvent", "parallel", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { close(parallelStarted) time.Sleep(250 * time.Millisecond) return "parallel", nil }, nil) - other := bus.Emit(abxbus.NewBaseEvent("FutureParallelSomeOtherEvent", nil)) + other := bus.EmitEventName("FutureParallelSomeOtherEvent", nil) select { case <-otherStarted: case <-time.After(time.Second): @@ -1564,11 +1564,11 @@ func TestWaitReturnsEventAcceptsTimeoutAndRejectsUnattachedPendingEvent(t *testi EventConcurrency: abxbus.EventConcurrencyBusSerial, }) releaseHandler := make(chan struct{}) - bus.On("EventCompletedTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventCompletedTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-releaseHandler return nil, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("EventCompletedTimeoutEvent", nil)) + event := bus.EmitEventName("EventCompletedTimeoutEvent", nil) if _, err := event.Wait(&abxbus.EventWaitOptions{Timeout: &timeout}); err == nil || !strings.Contains(err.Error(), "deadline") { t.Fatalf("Wait should time out, got %v", err) } @@ -1601,12 +1601,12 @@ func baseEventContainsString(values []string, needle string) bool { func TestBaseEventCarriesEventBusReferenceDuringDispatch(t *testing.T) { bus := abxbus.NewEventBus("ProxyBus", nil) var seenBus *abxbus.EventBus - bus.On("ProxyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ProxyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenBus = event.Bus return event.Bus.Name, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("ProxyEvent", nil)) + event := bus.EmitEventName("ProxyEvent", nil) result, err := event.EventResult() if err != nil { t.Fatal(err) @@ -1619,18 +1619,18 @@ func TestBaseEventCarriesEventBusReferenceDuringDispatch(t *testing.T) { func TestBaseEventBusReferenceReflectsForwardedProcessingBus(t *testing.T) { source := abxbus.NewEventBus("ProxySourceBus", nil) target := abxbus.NewEventBus("ProxyTargetBus", nil) - source.On("*", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + source.OnEventName("*", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { target.Emit(event) return "forwarded", nil }, nil) var targetSeenBus *abxbus.EventBus - target.On("ProxyForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + target.OnEventName("ProxyForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { targetSeenBus = event.Bus return event.Bus.Name, nil }, nil) - event := source.Emit(abxbus.NewBaseEvent("ProxyForwardEvent", nil)) + event := source.EmitEventName("ProxyForwardEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1653,29 +1653,29 @@ func TestBaseEventBusReferenceReflectsForwardedProcessingBus(t *testing.T) { func TestEventEmitFromForwardedHandlerDispatchesChildOnTargetBus(t *testing.T) { source := abxbus.NewEventBus("ProxyChildSourceBus", nil) target := abxbus.NewEventBus("ProxyChildTargetBus", nil) - source.On("*", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + source.OnEventName("*", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { target.Emit(event) return "forwarded", nil }, nil) var child *abxbus.BaseEvent var childSeenBus *abxbus.EventBus - targetHandler := target.On("ProxyParentEvent", "target_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + targetHandler := target.OnEventName("ProxyParentEvent", "target_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if event.Bus != target { t.Fatalf("target parent handler should see target bus, got %p want %p", event.Bus, target) } - child = event.Emit(abxbus.NewBaseEvent("ProxyChildEvent", nil)) + child = event.EmitEventName("ProxyChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } return "parent", nil }, nil) - target.On("ProxyChildEvent", "target_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + target.OnEventName("ProxyChildEvent", "target_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childSeenBus = event.Bus return "child", nil }, nil) - parent := source.Emit(abxbus.NewBaseEvent("ProxyParentEvent", nil)) + parent := source.EmitEventName("ProxyParentEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1713,7 +1713,7 @@ func mustJSON(t *testing.T, event *abxbus.BaseEvent) []byte { func TestBaseEventRuntimeStateTransitionsAndJSON(t *testing.T) { bus := abxbus.NewEventBus("RuntimeStateBus", nil) - bus.On("RuntimeStateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("RuntimeStateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if event.EventStatus != "started" { t.Fatalf("handler should see started status, got %s", event.EventStatus) } diff --git a/abxbus-go/tests/comprehensive_patterns_test.go b/abxbus-go/tests/comprehensive_patterns_test.go index 96f4fefd..6fa34a7d 100644 --- a/abxbus-go/tests/comprehensive_patterns_test.go +++ b/abxbus-go/tests/comprehensive_patterns_test.go @@ -85,26 +85,26 @@ func TestComprehensivePatternsForwardingDispatchAndParentTracking(t *testing.T) results = append(results, fmt.Sprintf("%04d:%s", sequence, label)) } - bus2.On("*", "child_bus2_event_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus2.OnEventName("*", "child_bus2_event_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { eventTypeShort := strings.TrimSuffix(e.EventType, "Event") next("bus2_handler_" + eventTypeShort) return "forwarded bus result", nil }, nil) - bus1.On("*", "emit", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("*", "emit", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return bus2.Emit(e), nil }, nil) var asyncChild *abxbus.BaseEvent var syncChild *abxbus.BaseEvent - bus1.On("ParentEvent", "parent_bus1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("ParentEvent", "parent_bus1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { next("parent_start") - asyncChild = e.Emit(abxbus.NewBaseEvent("QueuedChildEvent", nil)) + asyncChild = e.EmitEventName("QueuedChildEvent", nil) if asyncChild.EventStatus == "completed" { t.Fatalf("unawaited child should not be completed inside parent handler") } - syncChild = e.Emit(abxbus.NewBaseEvent("ImmediateChildEvent", nil)) + syncChild = e.EmitEventName("ImmediateChildEvent", nil) if _, err := syncChild.Now(); err != nil { return nil, err } @@ -122,7 +122,7 @@ func TestComprehensivePatternsForwardingDispatchAndParentTracking(t *testing.T) return "parent_done", nil }, nil) - parent := bus1.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + parent := bus1.EmitEventName("ParentEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -176,7 +176,7 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { var mu sync.Mutex results := []string{} - bus1.On("*", "forward_to_bus2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("*", "forward_to_bus2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return bus2.Emit(e), nil }, nil) @@ -184,7 +184,7 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { bus := bus for _, pattern := range []string{"QueuedChildEvent", "ImmediateChildEvent"} { pattern := pattern - bus.On(pattern, pattern+"_child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName(pattern, pattern+"_child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &results, "child_"+bus.Label()) time.Sleep(time.Millisecond) return "child_done_" + bus.Label(), nil @@ -192,13 +192,13 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { } } - bus1.On("RootEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("RootEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { children := []*abxbus.BaseEvent{} for i := 0; i < 3; i++ { - children = append(children, e.Emit(abxbus.NewBaseEvent("QueuedChildEvent", nil))) + children = append(children, e.EmitEventName("QueuedChildEvent", nil)) } for i := 0; i < 3; i++ { - child := e.Emit(abxbus.NewBaseEvent("ImmediateChildEvent", nil)) + child := e.EmitEventName("ImmediateChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } @@ -214,7 +214,7 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { } return "parent_done", nil }, nil) - bus1.On("RootEvent", "bad_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("RootEvent", "bad_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) @@ -223,7 +223,7 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { results = []string{} mu.Unlock() - event := bus1.Emit(abxbus.NewBaseEvent("RootEvent", nil)) + event := bus1.EmitEventName("RootEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -245,9 +245,9 @@ func TestComprehensiveAwaitedChildJumpsQueueWithoutOvershoot(t *testing.T) { var mu sync.Mutex order := []string{} - bus.On("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event1_start") - child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) + child := e.EmitEventName("ChildEvent", nil) appendLocked(&mu, &order, "Child_dispatched") if _, err := child.Now(); err != nil { return nil, err @@ -256,25 +256,25 @@ func TestComprehensiveAwaitedChildJumpsQueueWithoutOvershoot(t *testing.T) { appendLocked(&mu, &order, "Event1_end") return "event1_done", nil }, nil) - bus.On("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event2_start") appendLocked(&mu, &order, "Event2_end") return "event2_done", nil }, nil) - bus.On("Event3", "event3_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Event3", "event3_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event3_start") appendLocked(&mu, &order, "Event3_end") return "event3_done", nil }, nil) - bus.On("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Child_start") appendLocked(&mu, &order, "Child_end") return "child_done", nil }, nil) - event1 := bus.Emit(abxbus.NewBaseEvent("Event1", nil)) - event2 := bus.Emit(abxbus.NewBaseEvent("Event2", nil)) - event3 := bus.Emit(abxbus.NewBaseEvent("Event3", nil)) + event1 := bus.EmitEventName("Event1", nil) + event2 := bus.EmitEventName("Event2", nil) + event3 := bus.EmitEventName("Event3", nil) if _, err := event1.Now(); err != nil { t.Fatal(err) @@ -306,13 +306,13 @@ func TestComprehensiveDispatchMultipleAwaitOneSkipsOthersUntilAfterHandler(t *te var mu sync.Mutex order := []string{} - bus.On("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event1_start") - e.Emit(abxbus.NewBaseEvent("ChildA", nil)) + e.EmitEventName("ChildA", nil) appendLocked(&mu, &order, "ChildA_dispatched") - childB := e.Emit(abxbus.NewBaseEvent("ChildB", nil)) + childB := e.EmitEventName("ChildB", nil) appendLocked(&mu, &order, "ChildB_dispatched") - e.Emit(abxbus.NewBaseEvent("ChildC", nil)) + e.EmitEventName("ChildC", nil) appendLocked(&mu, &order, "ChildC_dispatched") if _, err := childB.Now(); err != nil { return nil, err @@ -323,16 +323,16 @@ func TestComprehensiveDispatchMultipleAwaitOneSkipsOthersUntilAfterHandler(t *te }, nil) for _, eventType := range []string{"Event2", "Event3", "ChildA", "ChildB", "ChildC"} { eventType := eventType - bus.On(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, eventType+"_start") appendLocked(&mu, &order, eventType+"_end") return strings.ToLower(eventType) + "_done", nil }, nil) } - event1 := bus.Emit(abxbus.NewBaseEvent("Event1", nil)) - bus.Emit(abxbus.NewBaseEvent("Event2", nil)) - bus.Emit(abxbus.NewBaseEvent("Event3", nil)) + event1 := bus.EmitEventName("Event1", nil) + bus.EmitEventName("Event2", nil) + bus.EmitEventName("Event3", nil) if _, err := event1.Now(); err != nil { t.Fatal(err) @@ -365,9 +365,9 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { bus2Started := make(chan struct{}) closeBus2Started := sync.Once{} - bus1.On("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Bus1_Event1_start") - child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) + child := e.EmitEventName("ChildEvent", nil) appendLocked(&mu, &order, "Child_dispatched_to_Bus1") if _, err := child.Now(); err != nil { return nil, err @@ -376,12 +376,12 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { appendLocked(&mu, &order, "Bus1_Event1_end") return "event1_done", nil }, nil) - bus1.On("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Bus1_Event2_start") appendLocked(&mu, &order, "Bus1_Event2_end") return "event2_done", nil }, nil) - bus1.On("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.OnEventName("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Child_start") select { case <-bus2Started: @@ -393,7 +393,7 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { }, nil) for _, eventType := range []string{"Event3", "Event4"} { eventType := eventType - bus2.On(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus2.OnEventName(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Bus2_"+eventType+"_start") if eventType == "Event3" { closeBus2Started.Do(func() { close(bus2Started) }) @@ -403,10 +403,10 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { }, nil) } - event1 := bus1.Emit(abxbus.NewBaseEvent("Event1", nil)) - bus1.Emit(abxbus.NewBaseEvent("Event2", nil)) - bus2.Emit(abxbus.NewBaseEvent("Event3", nil)) - bus2.Emit(abxbus.NewBaseEvent("Event4", nil)) + event1 := bus1.EmitEventName("Event1", nil) + bus1.EmitEventName("Event2", nil) + bus2.EmitEventName("Event3", nil) + bus2.EmitEventName("Event4", nil) waitForEntry(t, &mu, &order, "Bus2_Event3_start") if _, err := event1.Now(); err != nil { diff --git a/abxbus-go/tests/cross_runtime_roundtrip_test.go b/abxbus-go/tests/cross_runtime_roundtrip_test.go index 4a714243..e6cccc87 100644 --- a/abxbus-go/tests/cross_runtime_roundtrip_test.go +++ b/abxbus-go/tests/cross_runtime_roundtrip_test.go @@ -360,7 +360,7 @@ func assertGoHandlerResultAccepted(t *testing.T, eventPayload map[string]any, re isolateSchemaAssertionEvent(event) bus := abxbus.NewEventBus("GoRoundtripSchemaAccepted", nil) defer bus.Destroy() - bus.On(event.EventType, "valid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName(event.EventType, "valid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return result, nil }, nil) executed, err := bus.Emit(event).Now(&abxbus.EventWaitOptions{FirstResult: true}) @@ -379,7 +379,7 @@ func assertGoHandlerResultRejected(t *testing.T, eventPayload map[string]any, re isolateSchemaAssertionEvent(event) bus := abxbus.NewEventBus("GoRoundtripSchemaRejected", nil) defer bus.Destroy() - bus.On(event.EventType, "invalid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName(event.EventType, "invalid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return result, nil }, nil) executed, err := bus.Emit(event).Now(&abxbus.EventWaitOptions{FirstResult: true}) @@ -557,7 +557,7 @@ func TestJSONLEventBridgeForwardsEventsThroughFile(t *testing.T) { defer reader.Close() received := make(chan *abxbus.BaseEvent, 1) - reader.On("JSONLTestEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + reader.OnEventName("JSONLTestEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { received <- event return "ok", nil }, nil) @@ -593,7 +593,7 @@ func TestJSONLEventBridgeIgnoresMalformedLinesAndKeepsPolling(t *testing.T) { defer reader.Close() received := make(chan *abxbus.BaseEvent, 1) - reader.On("ValidEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + reader.OnEventName("ValidEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { received <- event return nil, nil }, nil) @@ -603,7 +603,7 @@ func TestJSONLEventBridgeIgnoresMalformedLinesAndKeepsPolling(t *testing.T) { } writer := abxbus.NewJSONLEventBridge(path, 0.01, "JSONLWriterMalformed") defer writer.Close() - if _, err := writer.Emit(abxbus.NewBaseEvent("ValidEvent", map[string]any{"ok": true})); err != nil { + if _, err := writer.EmitEventName("ValidEvent", map[string]any{"ok": true}); err != nil { t.Fatal(err) } @@ -690,7 +690,7 @@ func measureJSONLBridgeWarmLatencyMS(t *testing.T, jsonlPath string) float64 { measuredCount := 0 warmupOnce := sync.Once{} measuredOnce := sync.Once{} - receiver.On("IPCPingEvent", "latency_capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + receiver.OnEventName("IPCPingEvent", "latency_capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { label, _ := event.Payload["label"].(string) countsMu.Lock() defer countsMu.Unlock() diff --git a/abxbus-go/tests/event_handler_first_test.go b/abxbus-go/tests/event_handler_first_test.go index 03c636c4..0f268dde 100644 --- a/abxbus-go/tests/event_handler_first_test.go +++ b/abxbus-go/tests/event_handler_first_test.go @@ -18,15 +18,15 @@ func TestEventHandlerCompletionBusDefaultFirstSerial(t *testing.T) { }) secondHandlerCalled := false - bus.On("CompletionDefaultFirstEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionDefaultFirstEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.On("CompletionDefaultFirstEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionDefaultFirstEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondHandlerCalled = true return "second", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("CompletionDefaultFirstEvent", nil)) + event := bus.EmitEventName("CompletionDefaultFirstEvent", nil) if event.EventHandlerCompletion != "" { t.Fatalf("event_handler_completion should be unset on the event, got %s", event.EventHandlerCompletion) } @@ -58,10 +58,10 @@ func TestEventHandlerCompletionExplicitOverrideBeatsBusDefault(t *testing.T) { }) secondHandlerCalled := false - bus.On("CompletionOverrideEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionOverrideEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.On("CompletionOverrideEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionOverrideEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondHandlerCalled = true return "second", nil }, nil) @@ -87,7 +87,7 @@ func TestEventParallelFirstRacesAndCancelsNonWinners(t *testing.T) { }) var slowStarted atomic.Bool - bus.On("CompletionParallelFirstEvent", "slow_handler_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionParallelFirstEvent", "slow_handler_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { slowStarted.Store(true) select { case <-time.After(500 * time.Millisecond): @@ -96,11 +96,11 @@ func TestEventParallelFirstRacesAndCancelsNonWinners(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.On("CompletionParallelFirstEvent", "fast_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionParallelFirstEvent", "fast_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "winner", nil }, nil) - bus.On("CompletionParallelFirstEvent", "slow_handler_pending_or_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionParallelFirstEvent", "slow_handler_pending_or_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(500 * time.Millisecond): return "slow-other", nil @@ -154,11 +154,11 @@ func TestEventHandlerCompletionExplicitFirstCancelsParallelLosers(t *testing.T) }) var slowHandlerCompleted atomic.Bool - bus.On("CompletionFirstShortcutEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstShortcutEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.On("CompletionFirstShortcutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstShortcutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(500 * time.Millisecond): slowHandlerCompleted.Store(true) @@ -200,10 +200,10 @@ func TestEventHandlerCompletionFirstPreservesFalsyResults(t *testing.T) { }) secondHandlerCalled := false - bus.On("IntCompletionEvent", "zero_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("IntCompletionEvent", "zero_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return 0, nil }, nil) - bus.On("IntCompletionEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("IntCompletionEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondHandlerCalled = true return 99, nil }, nil) @@ -229,10 +229,10 @@ func TestEventHandlerCompletionFirstPreservesFalseAndEmptyStringResults(t *testi EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) boolSecondHandlerCalled := false - boolBus.On("BoolCompletionEvent", "bool_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + boolBus.OnEventName("BoolCompletionEvent", "bool_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return false, nil }, nil) - boolBus.On("BoolCompletionEvent", "bool_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + boolBus.OnEventName("BoolCompletionEvent", "bool_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { boolSecondHandlerCalled = true return true, nil }, nil) @@ -256,10 +256,10 @@ func TestEventHandlerCompletionFirstPreservesFalseAndEmptyStringResults(t *testi EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) strSecondHandlerCalled := false - strBus.On("StrCompletionEvent", "str_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + strBus.OnEventName("StrCompletionEvent", "str_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "", nil }, nil) - strBus.On("StrCompletionEvent", "str_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + strBus.OnEventName("StrCompletionEvent", "str_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { strSecondHandlerCalled = true return "second", nil }, nil) @@ -285,13 +285,13 @@ func TestEventHandlerCompletionFirstSkipsNoneResultAndUsesNextWinner(t *testing. EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) thirdHandlerCalled := false - bus.On("CompletionNoneSkipEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNoneSkipEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.On("CompletionNoneSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNoneSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - bus.On("CompletionNoneSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNoneSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { thirdHandlerCalled = true return "third", nil }, nil) @@ -325,13 +325,13 @@ func TestEventHandlerCompletionFirstSkipsBaseEventResultAndUsesNextWinner(t *tes EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) thirdHandlerCalled := false - bus.On("CompletionBaseEventSkipEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionBaseEventSkipEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return abxbus.NewBaseEvent("ChildCompletionEvent", nil), nil }, nil) - bus.On("CompletionBaseEventSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionBaseEventSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - bus.On("CompletionBaseEventSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionBaseEventSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { thirdHandlerCalled = true return "third", nil }, nil) @@ -360,16 +360,16 @@ func TestNowRunsAllHandlersAndEventResultReturnsFirstValidResult(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionFirst, }) lateCalled := false - bus.On("CompletionNowAllEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowAllEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return abxbus.NewBaseEvent("NowAllChildEvent", nil), nil }, nil) - bus.On("CompletionNowAllEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowAllEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.On("CompletionNowAllEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowAllEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - bus.On("CompletionNowAllEvent", "late_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowAllEvent", "late_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { lateCalled = true return "late", nil }, nil) @@ -394,7 +394,7 @@ func TestNowRunsAllHandlersAndEventResultReturnsFirstValidResult(t *testing.T) { func TestEventNowDefaultErrorPolicy(t *testing.T) { noHandlerBus := abxbus.NewEventBus("CompletionNowNoHandlerBus", nil) - noHandlerEvent, err := noHandlerBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() + noHandlerEvent, err := noHandlerBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -403,10 +403,10 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } noneBus := abxbus.NewEventBus("CompletionNowNoneBus", nil) - noneBus.On("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + noneBus.OnEventName("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - noneEvent, err := noneBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() + noneEvent, err := noneBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -415,13 +415,13 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } allErrorBus := abxbus.NewEventBus("CompletionNowAllErrorBus", nil) - allErrorBus.On("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + allErrorBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 1") }, nil) - allErrorBus.On("CompletionNowErrorPolicyEvent", "fail_two", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + allErrorBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_two", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 2") }, nil) - allErrorEvent, err := allErrorBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() + allErrorEvent, err := allErrorBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -430,13 +430,13 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } mixedValidBus := abxbus.NewEventBus("CompletionNowMixedValidBus", nil) - mixedValidBus.On("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedValidBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 1") }, nil) - mixedValidBus.On("CompletionNowErrorPolicyEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedValidBus.OnEventName("CompletionNowErrorPolicyEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - mixedValidEvent, err := mixedValidBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() + mixedValidEvent, err := mixedValidBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -445,13 +445,13 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } mixedNoneBus := abxbus.NewEventBus("CompletionNowMixedNoneBus", nil) - mixedNoneBus.On("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedNoneBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 1") }, nil) - mixedNoneBus.On("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedNoneBus.OnEventName("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - mixedNoneEvent, err := mixedNoneBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() + mixedNoneEvent, err := mixedNoneBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -464,17 +464,17 @@ func TestEventResultOptionsMatchEventResultsShape(t *testing.T) { bus := abxbus.NewEventBus("CompletionNowOptionsBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) - bus.On("CompletionNowOptionsEvent", "fail_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowOptionsEvent", "fail_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now option boom") }, nil) - bus.On("CompletionNowOptionsEvent", "first_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowOptionsEvent", "first_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.On("CompletionNowOptionsEvent", "second_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowOptionsEvent", "second_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "second", nil }, nil) - event, err := bus.Emit(abxbus.NewBaseEvent("CompletionNowOptionsEvent", nil)).Now() + event, err := bus.EmitEventName("CompletionNowOptionsEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -482,7 +482,7 @@ func TestEventResultOptionsMatchEventResultsShape(t *testing.T) { t.Fatalf("RaiseIfAny=true should surface handler errors, got %v", err) } - filteredEvent, err := bus.Emit(abxbus.NewBaseEvent("CompletionNowOptionsEvent", nil)).Now() + filteredEvent, err := bus.EmitEventName("CompletionNowOptionsEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -504,16 +504,16 @@ func TestEventResultReturnsFirstValidResultByRegistrationOrderAfterNow(t *testin bus := abxbus.NewEventBus("CompletionNowRegistrationOrderBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.On("CompletionNowRegistrationOrderEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowRegistrationOrderEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(50 * time.Millisecond) return "slow", nil }, nil) - bus.On("CompletionNowRegistrationOrderEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionNowRegistrationOrderEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(time.Millisecond) return "fast", nil }, nil) - event, err := bus.Emit(abxbus.NewBaseEvent("CompletionNowRegistrationOrderEvent", nil)).Now() + event, err := bus.EmitEventName("CompletionNowRegistrationOrderEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -527,10 +527,10 @@ func TestEventHandlerCompletionFirstReturnsNoneWhenAllHandlersFail(t *testing.T) bus := abxbus.NewEventBus("CompletionAllFailBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.On("CompletionAllFailEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionAllFailEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("boom1") }, nil) - bus.On("CompletionAllFailEvent", "fail_slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionAllFailEvent", "fail_slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return nil, assertErr("boom2") }, nil) @@ -551,10 +551,10 @@ func TestEventHandlerCompletionFirstResultOptionsMatchEventResultOptions(t *test bus := abxbus.NewEventBus("CompletionFirstOptionsBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.On("CompletionFirstOptionsEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstOptionsEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("first option boom") }, nil) - bus.On("CompletionFirstOptionsEvent", "slow_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstOptionsEvent", "slow_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "winner", nil }, nil) @@ -581,7 +581,7 @@ func TestEventHandlerCompletionFirstResultOptionsMatchEventResultOptions(t *test } noneBus := abxbus.NewEventBus("CompletionFirstRaiseNoneBus", nil) - noneBus.On("CompletionFirstRaiseNoneEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + noneBus.OnEventName("CompletionFirstRaiseNoneEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) noneEvent := abxbus.NewBaseEvent("CompletionFirstRaiseNoneEvent", nil) @@ -601,7 +601,7 @@ func TestNowFirstResultTimeoutLimitsProcessingWait(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, EventTimeout: &noTimeout, }) - bus.On("CompletionFirstTimeoutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstTimeoutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(500 * time.Millisecond) return "slow", nil }, nil) @@ -621,10 +621,10 @@ func TestEventResultIncludeCallbackReceivesResultAndEventResult(t *testing.T) { }) seenHandlerNames := []string{} seenResults := []any{} - bus.On("CompletionFirstIncludeEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstIncludeEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.On("CompletionFirstIncludeEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstIncludeEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "second", nil }, nil) @@ -661,14 +661,14 @@ func TestEventResultsIncludeCallbackReceivesResultAndEventResult(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) seenPairs := []string{} - bus.On("CompletionResultsListIncludeEvent", "keep_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionResultsListIncludeEvent", "keep_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "keep", nil }, nil) - bus.On("CompletionResultsListIncludeEvent", "drop_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionResultsListIncludeEvent", "drop_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "drop", nil }, nil) - event, err := bus.Emit(abxbus.NewBaseEvent("CompletionResultsListIncludeEvent", nil)).Now() + event, err := bus.EmitEventName("CompletionResultsListIncludeEvent", nil).Now() if err != nil { t.Fatal(err) } @@ -695,16 +695,16 @@ func TestEventResultReturnsFirstCurrentResultWithFirstResultWait(t *testing.T) { bus := abxbus.NewEventBus("CompletionFirstCurrentResultBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.On("CompletionFirstCurrentResultEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstCurrentResultEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(50 * time.Millisecond) return "slow", nil }, nil) - bus.On("CompletionFirstCurrentResultEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstCurrentResultEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(time.Millisecond) return "fast", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("CompletionFirstCurrentResultEvent", nil)) + event := bus.EmitEventName("CompletionFirstCurrentResultEvent", nil) if _, err := event.Now(&abxbus.EventWaitOptions{FirstResult: true}); err != nil { t.Fatal(err) } @@ -719,11 +719,11 @@ func TestEventResultRaiseIfAnyIncludesFirstModeControlErrors(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) - bus.On("CompletionFirstControlErrorEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstControlErrorEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.On("CompletionFirstControlErrorEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CompletionFirstControlErrorEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(500 * time.Millisecond): return "slow", nil diff --git a/abxbus-go/tests/event_handler_test.go b/abxbus-go/tests/event_handler_test.go index 74311c3c..e66e79fb 100644 --- a/abxbus-go/tests/event_handler_test.go +++ b/abxbus-go/tests/event_handler_test.go @@ -50,39 +50,39 @@ func TestEventBusOnSupportsEventFirstOptionalContextHandlerSignatures(t *testing bus := abxbus.NewEventBus("HandlerSignatureBus", nil) seen := []string{} - bus.On("HandlerSignatureEvent", "value_error", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("HandlerSignatureEvent", "value_error", func(event *abxbus.BaseEvent) (any, error) { seen = append(seen, event.EventType+":value_error") return "value_error", nil }, nil) - bus.On("HandlerSignatureEvent", "value_error_ctx", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("HandlerSignatureEvent", "value_error_ctx", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if ctx == nil { t.Fatal("context should be available when requested") } seen = append(seen, event.EventType+":value_error_ctx") return "value_error_ctx", nil }, nil) - bus.On("HandlerSignatureEvent", "error_only", func(event *abxbus.BaseEvent) error { + bus.OnEventName("HandlerSignatureEvent", "error_only", func(event *abxbus.BaseEvent) error { seen = append(seen, event.EventType+":error_only") return nil }, nil) - bus.On("HandlerSignatureEvent", "error_only_ctx", func(event *abxbus.BaseEvent, ctx context.Context) error { + bus.OnEventName("HandlerSignatureEvent", "error_only_ctx", func(event *abxbus.BaseEvent, ctx context.Context) error { if ctx == nil { t.Fatal("context should be available when requested") } seen = append(seen, event.EventType+":error_only_ctx") return nil }, nil) - bus.On("HandlerSignatureEvent", "void", func(event *abxbus.BaseEvent) { + bus.OnEventName("HandlerSignatureEvent", "void", func(event *abxbus.BaseEvent) { seen = append(seen, event.EventType+":void") }, nil) - bus.On("HandlerSignatureEvent", "void_ctx", func(event *abxbus.BaseEvent, ctx context.Context) { + bus.OnEventName("HandlerSignatureEvent", "void_ctx", func(event *abxbus.BaseEvent, ctx context.Context) { if ctx == nil { t.Fatal("context should be available when requested") } seen = append(seen, event.EventType+":void_ctx") }, nil) - values, err := bus.Emit(abxbus.NewBaseEvent("HandlerSignatureEvent", nil)).EventResultsList(&abxbus.EventResultOptions{ + values, err := bus.EmitEventName("HandlerSignatureEvent", nil).EventResultsList(&abxbus.EventResultOptions{ RaiseIfAny: false, RaiseIfNone: true, }) @@ -111,16 +111,16 @@ func TestEventBusOnTreatsTypedNilHandlersAsNoop(t *testing.T) { var voidCtx func(*abxbus.BaseEvent, context.Context) var named nilNamedHandler - bus.On("TypedNilHandlerEvent", "direct", direct, nil) - bus.On("TypedNilHandlerEvent", "value_error", valueError, nil) - bus.On("TypedNilHandlerEvent", "value_error_ctx", valueErrorCtx, nil) - bus.On("TypedNilHandlerEvent", "error_only", errorOnly, nil) - bus.On("TypedNilHandlerEvent", "error_only_ctx", errorOnlyCtx, nil) - bus.On("TypedNilHandlerEvent", "void", voidOnly, nil) - bus.On("TypedNilHandlerEvent", "void_ctx", voidCtx, nil) - bus.On("TypedNilHandlerEvent", "named", named, nil) + bus.OnEventName("TypedNilHandlerEvent", "direct", direct, nil) + bus.OnEventName("TypedNilHandlerEvent", "value_error", valueError, nil) + bus.OnEventName("TypedNilHandlerEvent", "value_error_ctx", valueErrorCtx, nil) + bus.OnEventName("TypedNilHandlerEvent", "error_only", errorOnly, nil) + bus.OnEventName("TypedNilHandlerEvent", "error_only_ctx", errorOnlyCtx, nil) + bus.OnEventName("TypedNilHandlerEvent", "void", voidOnly, nil) + bus.OnEventName("TypedNilHandlerEvent", "void_ctx", voidCtx, nil) + bus.OnEventName("TypedNilHandlerEvent", "named", named, nil) - values, err := bus.Emit(abxbus.NewBaseEvent("TypedNilHandlerEvent", nil)).EventResultsList(&abxbus.EventResultOptions{ + values, err := bus.EmitEventName("TypedNilHandlerEvent", nil).EventResultsList(&abxbus.EventResultOptions{ RaiseIfAny: true, RaiseIfNone: false, }) @@ -183,7 +183,7 @@ func TestOnRecomputesHandlerIDAfterMetadataOverrides(t *testing.T) { expectedID := "19ea9fe8-cfbe-541e-8a35-2579e4e9efff" bus := abxbus.NewEventBus("StandaloneBus", &abxbus.EventBusOptions{ID: eventbusID}) - entry := bus.On(eventPattern, "original_name", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + entry := bus.OnEventName(eventPattern, "original_name", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, &abxbus.EventHandler{ HandlerName: handlerName, diff --git a/abxbus-go/tests/event_result_test.go b/abxbus-go/tests/event_result_test.go index 6c0db71e..36239f73 100644 --- a/abxbus-go/tests/event_result_test.go +++ b/abxbus-go/tests/event_result_test.go @@ -178,14 +178,14 @@ func TestEventResultAllErrorOptionsContract(t *testing.T) { }) defer bus.Destroy() - bus.On("AllErrorResultOptionsEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("AllErrorResultOptionsEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("first failure") }, nil) - bus.On("AllErrorResultOptionsEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("AllErrorResultOptionsEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("second failure") }, nil) - event := bus.Emit(abxbus.NewBaseEvent("AllErrorResultOptionsEvent", nil)) + event := bus.EmitEventName("AllErrorResultOptionsEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -230,11 +230,11 @@ func TestEventResultAllErrorOptionsContract(t *testing.T) { func TestEventResultDefaultOptionsContract(t *testing.T) { errorBus := abxbus.NewEventBus("EventResultDefaultErrorOptionsBus", nil) - errorBus.On("DefaultErrorOptionsEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + errorBus.OnEventName("DefaultErrorOptionsEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("default boom") }, nil) - errorEvent := errorBus.Emit(abxbus.NewBaseEvent("DefaultErrorOptionsEvent", nil)) + errorEvent := errorBus.EmitEventName("DefaultErrorOptionsEvent", nil) if _, err := errorEvent.Now(); err != nil { t.Fatal(err) } @@ -260,7 +260,7 @@ func TestEventResultDefaultOptionsContract(t *testing.T) { errorBus.Destroy() emptyBus := abxbus.NewEventBus("EventResultDefaultNoneOptionsBus", nil) - emptyEvent := emptyBus.Emit(abxbus.NewBaseEvent("DefaultNoneOptionsEvent", nil)) + emptyEvent := emptyBus.EmitEventName("DefaultNoneOptionsEvent", nil) if _, err := emptyEvent.Now(); err != nil { t.Fatal(err) } @@ -283,17 +283,17 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { bus := abxbus.NewEventBus("EventResultErrorShapeBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.On("SingleErrorEvent", "single", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SingleErrorEvent", "single", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("single shape failure") }, nil) - bus.On("MultiErrorEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MultiErrorEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("first shape failure") }, nil) - bus.On("MultiErrorEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MultiErrorEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("second shape failure") }, nil) - single := bus.Emit(abxbus.NewBaseEvent("SingleErrorEvent", nil)) + single := bus.EmitEventName("SingleErrorEvent", nil) if _, err := single.Now(); err != nil { t.Fatal(err) } @@ -306,7 +306,7 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { t.Fatalf("single handler failure should not use EventHandlerErrors, got %#v", singleHandlerErrors) } - event := bus.Emit(abxbus.NewBaseEvent("MultiErrorEvent", nil)) + event := bus.EmitEventName("MultiErrorEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -326,7 +326,7 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { } emptyBus := abxbus.NewEventBus("EventResultNoneShapeBus", nil) - empty := emptyBus.Emit(abxbus.NewBaseEvent("EmptyResultEvent", nil)) + empty := emptyBus.EmitEventName("EmptyResultEvent", nil) if _, err := empty.Now(); err != nil { t.Fatal(err) } @@ -346,11 +346,11 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { func TestEventResultOptions(t *testing.T) { bus := abxbus.NewEventBus("ResultsListBus", nil) - bus.On("ListEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.On("ListEvent", "nil", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.On("ListEvent", "err", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) + bus.OnEventName("ListEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) + bus.OnEventName("ListEvent", "nil", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) + bus.OnEventName("ListEvent", "err", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - e := bus.Emit(abxbus.NewBaseEvent("ListEvent", nil)) + e := bus.EmitEventName("ListEvent", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -389,12 +389,12 @@ func TestEventResultOptions(t *testing.T) { slowBus := abxbus.NewEventBus("ResultsListTimeoutBus", nil) started := make(chan struct{}, 1) release := make(chan struct{}) - slowBus.On("SlowListEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + slowBus.OnEventName("SlowListEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return "late", nil }, nil) - slow := slowBus.Emit(abxbus.NewBaseEvent("SlowListEvent", nil)) + slow := slowBus.EmitEventName("SlowListEvent", nil) select { case <-started: case <-time.After(2 * time.Second): @@ -417,22 +417,22 @@ func TestEventResultAndResultsListUseRegistrationOrderForCurrentResultSubset(t * EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) completedOrder := make(chan string, 3) - bus.On("OrderResultEvent", "null", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("OrderResultEvent", "null", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) completedOrder <- "null" return nil, nil }, &abxbus.EventHandler{ID: "m-null"}) - bus.On("OrderResultEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("OrderResultEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(20 * time.Millisecond) completedOrder <- "winner" return "winner", nil }, &abxbus.EventHandler{ID: "z-winner"}) - bus.On("OrderResultEvent", "late", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("OrderResultEvent", "late", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { completedOrder <- "late" return "late", nil }, &abxbus.EventHandler{ID: "a-late"}) - e := bus.Emit(abxbus.NewBaseEvent("OrderResultEvent", nil)) + e := bus.EmitEventName("OrderResultEvent", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -563,14 +563,14 @@ func TestEventResultSerializesHandlerMetadataAndDerivedFields(t *testing.T) { bus := abxbus.NewEventBus("ResultMetadataBus", nil) timeout := 1.5 slowTimeout := 0.25 - handler := bus.On("MetadataEvent", "metadata_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.OnEventName("MetadataEvent", "metadata_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, &abxbus.EventHandler{ HandlerTimeout: &timeout, HandlerSlowTimeout: &slowTimeout, }) - event := bus.Emit(abxbus.NewBaseEvent("MetadataEvent", nil)) + event := bus.EmitEventName("MetadataEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -614,7 +614,7 @@ func assertSchemaResult(t *testing.T, name string, schema map[string]any, value t.Helper() bus := abxbus.NewEventBus(name+"Bus", nil) eventType := name + "Event" - bus.On(eventType, "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName(eventType, "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return value, nil }, nil) event := bus.Emit(schemaEvent(eventType, schema)) @@ -651,7 +651,7 @@ func TestTypedResultSchemaValidatesHandlerResult(t *testing.T) { }, "required": []any{"value", "count"}, } - bus.On("TypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"value": "hello", "count": 42}, nil }, nil) @@ -667,10 +667,10 @@ func TestTypedResultSchemaValidatesHandlerResult(t *testing.T) { func TestBuiltinResultSchemaValidatesHandlerResults(t *testing.T) { bus := abxbus.NewEventBus("BuiltinResultSchemaBus", nil) - bus.On("BuiltinStringResultEvent", "string_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("BuiltinStringResultEvent", "string_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "42", nil }, nil) - bus.On("BuiltinIntResultEvent", "int_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("BuiltinIntResultEvent", "int_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return 123, nil }, nil) @@ -703,7 +703,7 @@ func TestInvalidHandlerResultMarksErrorWhenSchemaIsDefined(t *testing.T) { "required": []any{"value"}, "additionalProperties": false, } - bus.On("InvalidTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("InvalidTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"value": 123, "extra": true}, nil }, nil) @@ -723,11 +723,11 @@ func TestInvalidHandlerResultMarksErrorWhenSchemaIsDefined(t *testing.T) { func TestNoSchemaLeavesRawHandlerResultUntouched(t *testing.T) { bus := abxbus.NewEventBus("NoSchemaResultBus", nil) raw := map[string]any{"value": 123} - bus.On("NoSchemaEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NoSchemaEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return raw, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("NoSchemaEvent", nil)) + event := bus.EmitEventName("NoSchemaEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -760,7 +760,7 @@ func TestComplexResultSchemaValidatesNestedData(t *testing.T) { }, "required": []any{"items"}, } - bus.On("ComplexTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ComplexTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"items": []any{map[string]any{"id": 1, "labels": []any{"a", "b"}}}}, nil }, nil) @@ -929,7 +929,7 @@ func TestSchemaReferencesAndAnyOfAreEnforced(t *testing.T) { }, "$ref": "#/$defs/Payload", } - bus.On("SchemaRefEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SchemaRefEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"value": 7}, nil }, nil) @@ -1009,11 +1009,11 @@ func TestEmitAcceptsTypedStructAndDerivesPayloadAndConfig(t *testing.T) { func TestTypedEventPayloadAndResultHelpers(t *testing.T) { bus := abxbus.NewEventBus("TypedBus", nil) - abxbus.OnTyped[addPayload, addResult](bus, "AddEvent", "add", func(payload addPayload) (addResult, error) { + bus.On("AddEvent", "add", func(payload addPayload) (addResult, error) { return addResult{Sum: payload.A + payload.B}, nil }, nil) - event := abxbus.MustNewTypedEventWithResult[addPayload, addResult]("AddEvent", addPayload{A: 4, B: 9}) + event := abxbus.MustNewEvent("AddEvent", addPayload{A: 4, B: 9}, abxbus.ResultType[addResult]()) result, err := bus.Emit(event).EventResult() if err != nil { t.Fatal(err) @@ -1035,19 +1035,19 @@ func TestTypedEventPayloadAndResultHelpers(t *testing.T) { } } -func TestOnTypedSupportsOptionalContextHandlerSignatures(t *testing.T) { +func TestOnSupportsOptionalContextHandlerSignatures(t *testing.T) { bus := abxbus.NewEventBus("TypedOptionalContextBus", nil) - abxbus.OnTyped[addPayload, addResult](bus, "TypedNoContextEvent", "typed", func(payload addPayload) addResult { + bus.On("TypedNoContextEvent", "typed", func(payload addPayload) addResult { return addResult{Sum: payload.A + payload.B} }, nil) gotCtx := false - abxbus.OnTyped[addPayload, addResult](bus, "TypedWithContextEvent", "typed", func(payload addPayload, ctx context.Context) (addResult, error) { + bus.On("TypedWithContextEvent", "typed", func(payload addPayload, ctx context.Context) (addResult, error) { gotCtx = ctx != nil return addResult{Sum: payload.A + payload.B}, nil }, nil) - noCtxEvent := bus.Emit(abxbus.MustNewTypedEventWithResult[addPayload, addResult]("TypedNoContextEvent", addPayload{A: 2, B: 3})) + noCtxEvent := bus.Emit(abxbus.MustNewEvent("TypedNoContextEvent", addPayload{A: 2, B: 3}, abxbus.ResultType[addResult]())) if _, err := noCtxEvent.Now(); err != nil { t.Fatal(err) } @@ -1063,7 +1063,7 @@ func TestOnTypedSupportsOptionalContextHandlerSignatures(t *testing.T) { t.Fatalf("expected typed no-context result sum=5, got %#v", noCtxTypedResult) } - ctxEvent := bus.Emit(abxbus.MustNewTypedEventWithResult[addPayload, addResult]("TypedWithContextEvent", addPayload{A: 4, B: 6})) + ctxEvent := bus.Emit(abxbus.MustNewEvent("TypedWithContextEvent", addPayload{A: 4, B: 6}, abxbus.ResultType[addResult]())) if _, err := ctxEvent.Now(); err != nil { t.Fatal(err) } @@ -1085,16 +1085,16 @@ func TestEventBusOnSupportsNamedHandlerFunctionTypes(t *testing.T) { gotNoContext := false gotContext := false - bus.On("NamedNoContextHandlerEvent", "named_no_context", namedBaseNoContextHandler(func(event *abxbus.BaseEvent) error { + bus.OnEventName("NamedNoContextHandlerEvent", "named_no_context", namedBaseNoContextHandler(func(event *abxbus.BaseEvent) error { gotNoContext = event.EventType == "NamedNoContextHandlerEvent" return nil }), nil) - bus.On("NamedWithContextHandlerEvent", "named_with_context", namedBaseWithContextHandler(func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NamedWithContextHandlerEvent", "named_with_context", namedBaseWithContextHandler(func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { gotContext = event.EventType == "NamedWithContextHandlerEvent" && ctx != nil return "named-ok", nil }), nil) - noContextEvent := bus.Emit(abxbus.NewBaseEvent("NamedNoContextHandlerEvent", nil)) + noContextEvent := bus.EmitEventName("NamedNoContextHandlerEvent", nil) if _, err := noContextEvent.Now(); err != nil { t.Fatal(err) } @@ -1102,7 +1102,7 @@ func TestEventBusOnSupportsNamedHandlerFunctionTypes(t *testing.T) { t.Fatal("expected named no-context handler to run") } - contextEvent := bus.Emit(abxbus.NewBaseEvent("NamedWithContextHandlerEvent", nil)) + contextEvent := bus.EmitEventName("NamedWithContextHandlerEvent", nil) if _, err := contextEvent.Now(); err != nil { t.Fatal(err) } @@ -1115,19 +1115,19 @@ func TestEventBusOnSupportsNamedHandlerFunctionTypes(t *testing.T) { } } -func TestOnTypedSupportsNamedHandlerFunctionTypes(t *testing.T) { +func TestOnSupportsNamedHandlerFunctionTypes(t *testing.T) { bus := abxbus.NewEventBus("TypedNamedHandlerFunctionTypesBus", nil) gotCtx := false - abxbus.OnTyped[addPayload, addResult](bus, "TypedNamedNoContextEvent", "typed", namedTypedNoContextHandler(func(payload addPayload) addResult { + bus.On("TypedNamedNoContextEvent", "typed", namedTypedNoContextHandler(func(payload addPayload) addResult { return addResult{Sum: payload.A + payload.B} }), nil) - abxbus.OnTyped[addPayload, addResult](bus, "TypedNamedWithContextEvent", "typed", namedTypedWithContextHandler(func(payload addPayload, ctx context.Context) (addResult, error) { + bus.On("TypedNamedWithContextEvent", "typed", namedTypedWithContextHandler(func(payload addPayload, ctx context.Context) (addResult, error) { gotCtx = ctx != nil return addResult{Sum: payload.A + payload.B}, nil }), nil) - noContextEvent := bus.Emit(abxbus.MustNewTypedEventWithResult[addPayload, addResult]("TypedNamedNoContextEvent", addPayload{A: 3, B: 4})) + noContextEvent := bus.Emit(abxbus.MustNewEvent("TypedNamedNoContextEvent", addPayload{A: 3, B: 4}, abxbus.ResultType[addResult]())) if _, err := noContextEvent.Now(); err != nil { t.Fatal(err) } @@ -1143,7 +1143,7 @@ func TestOnTypedSupportsNamedHandlerFunctionTypes(t *testing.T) { t.Fatalf("expected named typed no-context result sum=7, got %#v", noContextTypedResult) } - contextEvent := bus.Emit(abxbus.MustNewTypedEventWithResult[addPayload, addResult]("TypedNamedWithContextEvent", addPayload{A: 5, B: 8})) + contextEvent := bus.Emit(abxbus.MustNewEvent("TypedNamedWithContextEvent", addPayload{A: 5, B: 8}, abxbus.ResultType[addResult]())) if _, err := contextEvent.Now(); err != nil { t.Fatal(err) } @@ -1160,11 +1160,11 @@ func TestOnTypedSupportsNamedHandlerFunctionTypes(t *testing.T) { } } -func TestOnTypedNamedAnyHandlerAcceptsNilPayload(t *testing.T) { +func TestOnNamedAnyHandlerAcceptsNilPayload(t *testing.T) { bus := abxbus.NewEventBus("TypedNamedAnyNilPayloadBus", nil) called := false - abxbus.OnTyped[any, addResult](bus, "TypedNamedAnyNilPayloadEvent", "typed", namedTypedAnyHandler(func(payload any) (addResult, error) { + bus.On("TypedNamedAnyNilPayloadEvent", "typed", namedTypedAnyHandler(func(payload any) (addResult, error) { called = true if payload != nil { t.Fatalf("expected nil payload, got %#v", payload) @@ -1195,50 +1195,50 @@ func TestEventPayloadAsRejectsNilEvent(t *testing.T) { func TestTypedEventWithResultSchemaValidatesHandlerReturnAtRuntime(t *testing.T) { bus := abxbus.NewEventBus("TypedSchemaBus", nil) - bus.On("TypedSchemaEvent", "bad", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TypedSchemaEvent", "bad", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"sum": "not-an-int"}, nil }, nil) - event := abxbus.MustNewTypedEventWithResult[addPayload, addResult]("TypedSchemaEvent", addPayload{A: 1, B: 2}) + event := abxbus.MustNewEvent("TypedSchemaEvent", addPayload{A: 1, B: 2}, abxbus.ResultType[addResult]()) if _, err := bus.Emit(event).EventResult(); err == nil || !strings.Contains(err.Error(), "EventHandlerResultSchemaError") { t.Fatalf("expected typed result schema error, got %v", err) } } -func TestOnTypedValidatesPayloadBeforeCallingHandler(t *testing.T) { +func TestOnValidatesPayloadBeforeCallingHandler(t *testing.T) { bus := abxbus.NewEventBus("TypedPayloadSchemaBus", nil) called := false - abxbus.OnTyped[addPayload, addResult](bus, "TypedPayloadSchemaEvent", "typed", func(payload addPayload, ctx context.Context) (addResult, error) { + bus.On("TypedPayloadSchemaEvent", "typed", func(payload addPayload, ctx context.Context) (addResult, error) { called = true return addResult{Sum: payload.A + payload.B}, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("TypedPayloadSchemaEvent", map[string]any{"a": 1})) + event := bus.EmitEventName("TypedPayloadSchemaEvent", map[string]any{"a": 1}) if _, err := event.Now(); err != nil { t.Fatal(err) } if called { - t.Fatal("typed handler should not be called when a required payload field is missing") + t.Fatal("handler should not be called when a required payload field is missing") } if _, err := event.EventResult(); err == nil || !strings.Contains(err.Error(), "EventHandlerPayloadSchemaError") { t.Fatalf("expected typed payload schema error, got %v", err) } } -func TestOnTypedRejectsWrongPayloadFieldType(t *testing.T) { +func TestOnRejectsWrongPayloadFieldType(t *testing.T) { bus := abxbus.NewEventBus("TypedPayloadTypeBus", nil) called := false - abxbus.OnTyped[addPayload, addResult](bus, "TypedPayloadTypeEvent", "typed", func(payload addPayload, ctx context.Context) (addResult, error) { + bus.On("TypedPayloadTypeEvent", "typed", func(payload addPayload, ctx context.Context) (addResult, error) { called = true return addResult{Sum: payload.A + payload.B}, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("TypedPayloadTypeEvent", map[string]any{"a": "one", "b": 2})) + event := bus.EmitEventName("TypedPayloadTypeEvent", map[string]any{"a": "one", "b": 2}) if _, err := event.Now(); err != nil { t.Fatal(err) } if called { - t.Fatal("typed handler should not be called when a payload field has the wrong type") + t.Fatal("handler should not be called when a payload field has the wrong type") } if _, err := event.EventResult(); err == nil || !strings.Contains(err.Error(), "EventHandlerPayloadSchemaError") { t.Fatalf("expected typed payload schema error, got %v", err) diff --git a/abxbus-go/tests/eventbus_cross_runtime_features_test.go b/abxbus-go/tests/eventbus_cross_runtime_features_test.go index 097d4030..5b090903 100644 --- a/abxbus-go/tests/eventbus_cross_runtime_features_test.go +++ b/abxbus-go/tests/eventbus_cross_runtime_features_test.go @@ -38,16 +38,16 @@ func TestQueueJumpPreservesParentChildLineageAndFindVisibility(t *testing.T) { executionOrder = append(executionOrder, value) } - bus.On("QueueJumpRootEvent", "on_root", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("QueueJumpRootEvent", "on_root", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendOrder("root:start") - child := event.Emit(abxbus.NewBaseEvent("QueueJumpChildEvent", nil)) + child := event.EmitEventName("QueueJumpChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } appendOrder("root:end") return "root-ok", nil }, nil) - bus.On("QueueJumpChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("QueueJumpChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() childEventID = event.EventID mu.Unlock() @@ -59,13 +59,13 @@ func TestQueueJumpPreservesParentChildLineageAndFindVisibility(t *testing.T) { } return "child-ok", nil }, nil) - bus.On("QueueJumpSiblingEvent", "on_sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("QueueJumpSiblingEvent", "on_sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendOrder("sibling") return "sibling-ok", nil }, nil) - root := bus.Emit(abxbus.NewBaseEvent("QueueJumpRootEvent", nil)) - sibling := bus.Emit(abxbus.NewBaseEvent("QueueJumpSiblingEvent", nil)) + root := bus.EmitEventName("QueueJumpRootEvent", nil) + sibling := bus.EmitEventName("QueueJumpSiblingEvent", nil) if _, err := root.Now(); err != nil { t.Fatal(err) } @@ -93,7 +93,7 @@ func TestQueueJumpPreservesParentChildLineageAndFindVisibility(t *testing.T) { t.Fatal("child handler did not capture child event id") } - foundChild, err := bus.Find("QueueJumpChildEvent", nil, &abxbus.FindOptions{Past: true, Future: false, ChildOf: root}) + foundChild, err := bus.FindEventName("QueueJumpChildEvent", nil, &abxbus.FindOptions{Past: true, Future: false, ChildOf: root}) if err != nil { t.Fatal(err) } @@ -164,12 +164,12 @@ func TestConcurrencyIntersectionParallelEventsWithSerialHandlers(t *testing.T) { mu.Unlock() return "ok", nil } - bus.On("ConcurrencyIntersectionEvent", "tracked_handler_a", trackedHandler, nil) - bus.On("ConcurrencyIntersectionEvent", "tracked_handler_b", trackedHandler, nil) + bus.OnEventName("ConcurrencyIntersectionEvent", "tracked_handler_a", trackedHandler, nil) + bus.OnEventName("ConcurrencyIntersectionEvent", "tracked_handler_b", trackedHandler, nil) events := make([]*abxbus.BaseEvent, 0, 8) for idx := 0; idx < 8; idx++ { - events = append(events, bus.Emit(abxbus.NewBaseEvent("ConcurrencyIntersectionEvent", map[string]any{"token": idx}))) + events = append(events, bus.EmitEventName("ConcurrencyIntersectionEvent", map[string]any{"token": idx})) } for _, event := range events { if _, err := event.Wait(); err != nil { @@ -202,15 +202,15 @@ func TestTimeoutEnforcementDoesNotBreakFollowupProcessingOrQueueState(t *testing EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) t.Cleanup(bus.Destroy) - bus.On("TimeoutEnforcementEvent", "slow_handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutEnforcementEvent", "slow_handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, nil) - bus.On("TimeoutEnforcementEvent", "slow_handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutEnforcementEvent", "slow_handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, nil) - bus.On("TimeoutFollowupEvent", "followup_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutFollowupEvent", "followup_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "followup-ok", nil }, nil) @@ -231,7 +231,7 @@ func TestTimeoutEnforcementDoesNotBreakFollowupProcessingOrQueueState(t *testing } } - followup := bus.Emit(abxbus.NewBaseEvent("TimeoutFollowupEvent", nil)) + followup := bus.EmitEventName("TimeoutFollowupEvent", nil) if _, err := followup.Now(); err != nil { t.Fatal(err) } @@ -262,18 +262,18 @@ func TestZeroHistoryBackpressureWithFindFutureStillResolvesNewEvents(t *testing. MaxHistoryDrop: false, }) t.Cleanup(bus.Destroy) - bus.On("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok:" + event.Payload["value"].(string), nil }, nil) - first := bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "first"})) + first := bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "first"}) if _, err := first.Now(); err != nil { t.Fatal(err) } if bus.EventHistory.Has(first.EventID) { t.Fatal("max_history_size=0 should drop completed events from history") } - past, err := bus.Find("ZeroHistoryEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + past, err := bus.FindEventName("ZeroHistoryEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -284,10 +284,10 @@ func TestZeroHistoryBackpressureWithFindFutureStillResolvesNewEvents(t *testing. capturedFutureID := make(chan string, 1) go func() { time.Sleep(20 * time.Millisecond) - futureEvent := bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "future"})) + futureEvent := bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "future"}) capturedFutureID <- futureEvent.EventID }() - futureMatch, err := bus.Find("ZeroHistoryEvent", func(event *abxbus.BaseEvent) bool { + futureMatch, err := bus.FindEventName("ZeroHistoryEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["value"] == "future" }, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { @@ -319,19 +319,19 @@ func TestContextPropagatesThroughForwardingAndChildDispatchWithLineageIntact(t * parentEventID := "" childParentID := "" - busA.On("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return busB.Emit(event), nil }, nil) - busB.On("ContextParentEvent", "on_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ContextParentEvent", "on_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { capturedParentRequestID, _ = ctx.Value(key).(string) parentEventID = event.EventID - child := event.Emit(abxbus.NewBaseEvent("ContextChildEvent", nil)) + child := event.EmitEventName("ContextChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } return "parent-ok", nil }, nil) - busB.On("ContextChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ContextChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { capturedChildRequestID, _ = ctx.Value(key).(string) if event.EventParentID != nil { childParentID = *event.EventParentID @@ -341,7 +341,7 @@ func TestContextPropagatesThroughForwardingAndChildDispatchWithLineageIntact(t * requestID := "fc81f432-98cd-7a06-824c-dafed74761bb" ctx := context.WithValue(context.Background(), key, requestID) - parent := busA.EmitWithContext(ctx, abxbus.NewBaseEvent("ContextParentEvent", nil)) + parent := busA.EmitEventNameWithContext(ctx, "ContextParentEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -371,7 +371,7 @@ func TestContextPropagatesThroughForwardingAndChildDispatchWithLineageIntact(t * t.Fatalf("parent event path did not include target bus: %#v", parent.EventPath) } - foundChild, err := busB.Find("ContextChildEvent", nil, &abxbus.FindOptions{Past: true, Future: false, ChildOf: parent}) + foundChild, err := busB.FindEventName("ContextChildEvent", nil, &abxbus.FindOptions{Past: true, Future: false, ChildOf: parent}) if err != nil { t.Fatal(err) } @@ -391,7 +391,7 @@ func TestPendingQueueFindVisibilityTransitionsToCompletedAfterRelease(t *testing started := make(chan struct{}) release := make(chan struct{}) var once sync.Once - bus.On("PendingVisibilityEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PendingVisibilityEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if event.Payload["tag"] == "blocking" { once.Do(func() { close(started) }) select { @@ -403,12 +403,12 @@ func TestPendingQueueFindVisibilityTransitionsToCompletedAfterRelease(t *testing return "ok:" + event.Payload["tag"].(string), nil }, nil) - blocking := bus.Emit(abxbus.NewBaseEvent("PendingVisibilityEvent", map[string]any{"tag": "blocking"})) + blocking := bus.EmitEventName("PendingVisibilityEvent", map[string]any{"tag": "blocking"}) testWaitForSignal(t, started, 2*time.Second, "blocking event start") - queued := bus.Emit(abxbus.NewBaseEvent("PendingVisibilityEvent", map[string]any{"tag": "queued"})) + queued := bus.EmitEventName("PendingVisibilityEvent", map[string]any{"tag": "queued"}) time.Sleep(10 * time.Millisecond) - foundQueued, err := bus.Find("PendingVisibilityEvent", func(event *abxbus.BaseEvent) bool { + foundQueued, err := bus.FindEventName("PendingVisibilityEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["tag"] == "queued" }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -439,19 +439,19 @@ func TestHistoryBackpressureRejectsOverflowAndPreservesFindableHistory(t *testin MaxHistoryDrop: false, }) t.Cleanup(bus.Destroy) - bus.On("BackpressureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("BackpressureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok:" + event.Payload["value"].(string), nil }, nil) - first := bus.Emit(abxbus.NewBaseEvent("BackpressureEvent", map[string]any{"value": "first"})) - second := bus.Emit(abxbus.NewBaseEvent("BackpressureEvent", map[string]any{"value": "second"})) + first := bus.EmitEventName("BackpressureEvent", map[string]any{"value": "first"}) + second := bus.EmitEventName("BackpressureEvent", map[string]any{"value": "second"}) if _, err := first.Now(); err != nil { t.Fatal(err) } if _, err := second.Now(); err != nil { t.Fatal(err) } - foundFirst, err := bus.Find("BackpressureEvent", nil, &abxbus.FindOptions{ + foundFirst, err := bus.FindEventName("BackpressureEvent", nil, &abxbus.FindOptions{ Past: true, Future: false, Equals: map[string]any{"value": "first"}, @@ -471,7 +471,7 @@ func TestHistoryBackpressureRejectsOverflowAndPreservesFindableHistory(t *testin t.Fatalf("history size should remain capped after rejected overflow, got %d", bus.EventHistory.Size()) } }() - bus.Emit(abxbus.NewBaseEvent("BackpressureEvent", map[string]any{"value": "overflow"})) + bus.EmitEventName("BackpressureEvent", map[string]any{"value": "overflow"}) } func TestEventBusCrossRuntimeJSONFeaturesUseCanonicalShapes(t *testing.T) { @@ -479,7 +479,7 @@ func TestEventBusCrossRuntimeJSONFeaturesUseCanonicalShapes(t *testing.T) { bus := abxbus.NewEventBus("CrossRuntimeFeatureBus", &abxbus.EventBusOptions{ EventHandlerDetectFilePaths: &detectPaths, }) - handler := bus.On("CrossRuntimeFeatureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.OnEventName("CrossRuntimeFeatureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"ok": true}, nil }, nil) event := abxbus.NewBaseEvent("CrossRuntimeFeatureEvent", map[string]any{"label": "go"}) diff --git a/abxbus-go/tests/eventbus_debounce_test.go b/abxbus-go/tests/eventbus_debounce_test.go index a677dbc3..b78497f1 100644 --- a/abxbus-go/tests/eventbus_debounce_test.go +++ b/abxbus-go/tests/eventbus_debounce_test.go @@ -15,25 +15,25 @@ func debounceEmitFallback(bus *abxbus.EventBus, eventType string, payload map[st if found != nil { return found } - return bus.Emit(abxbus.NewBaseEvent(eventType, payload)) + return bus.EmitEventName(eventType, payload) } func TestSimpleDebounceWithChildOfReusesRecentEvent(t *testing.T) { bus := abxbus.NewEventBus("DebounceBus", nil) - bus.On("ScreenshotEvent", "complete_screenshot", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ScreenshotEvent", "complete_screenshot", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "screenshot_done", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + parent := bus.EmitEventName("ParentEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } - child := parent.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) + child := parent.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) if _, err := child.Now(); err != nil { t.Fatal(err) } - found, err := bus.Find("ScreenshotEvent", nil, &abxbus.FindOptions{ + found, err := bus.FindEventName("ScreenshotEvent", nil, &abxbus.FindOptions{ Past: 10.0, Future: false, ChildOf: parent, @@ -56,11 +56,11 @@ func TestSimpleDebounceWithChildOfReusesRecentEvent(t *testing.T) { func TestReturnsExistingFreshEvent(t *testing.T) { bus := abxbus.NewEventBus("DebounceFreshBus", nil) - bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) - original := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) + original := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) if _, err := original.Now(); err != nil { t.Fatal(err) } @@ -75,7 +75,7 @@ func TestReturnsExistingFreshEvent(t *testing.T) { } return time.Since(completedAt) < 5*time.Second } - found, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID1 && isFresh(event) }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -96,7 +96,7 @@ func TestAdvancedDebouncePrefersHistoryThenWaitsFutureThenDispatches(t *testing. errs := make(chan error, 1) go func() { - found, err := bus.Find("SyncEvent", nil, &abxbus.FindOptions{Past: false, Future: 0.5}) + found, err := bus.FindEventName("SyncEvent", nil, &abxbus.FindOptions{Past: false, Future: 0.5}) if err != nil { errs <- err return @@ -105,12 +105,12 @@ func TestAdvancedDebouncePrefersHistoryThenWaitsFutureThenDispatches(t *testing. }() go func() { time.Sleep(50 * time.Millisecond) - bus.Emit(abxbus.NewBaseEvent("SyncEvent", nil)) + bus.EmitEventName("SyncEvent", nil) }() ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - historyMatch, err := bus.Find("SyncEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + historyMatch, err := bus.FindEventName("SyncEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -127,7 +127,7 @@ func TestAdvancedDebouncePrefersHistoryThenWaitsFutureThenDispatches(t *testing. resolved = futureMatch } if resolved == nil { - resolved = bus.Emit(abxbus.NewBaseEvent("SyncEvent", nil)) + resolved = bus.EmitEventName("SyncEvent", nil) } if _, err := resolved.Now(); err != nil { t.Fatal(err) @@ -139,11 +139,11 @@ func TestAdvancedDebouncePrefersHistoryThenWaitsFutureThenDispatches(t *testing. func TestDispatchesNewWhenNoMatch(t *testing.T) { bus := abxbus.NewEventBus("DebounceNoMatchBus", nil) - bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) - found, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID1 }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -163,15 +163,15 @@ func TestDispatchesNewWhenNoMatch(t *testing.T) { func TestDispatchesNewWhenStale(t *testing.T) { bus := abxbus.NewEventBus("DebounceStaleBus", nil) - bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) - original := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) + original := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) if _, err := original.Now(); err != nil { t.Fatal(err) } - found, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID1 && false }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -196,7 +196,7 @@ func TestDispatchesNewWhenStale(t *testing.T) { func TestFindPastOnlyReturnsImmediatelyWithoutWaiting(t *testing.T) { bus := abxbus.NewEventBus("DebouncePastOnlyBus", nil) start := time.Now() - result, err := bus.Find("ParentEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + result, err := bus.FindEventName("ParentEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -212,7 +212,7 @@ func TestFindPastOnlyReturnsImmediatelyWithoutWaiting(t *testing.T) { func TestFindPastFloatReturnsImmediatelyWithoutWaiting(t *testing.T) { bus := abxbus.NewEventBus("DebouncePastWindowBus", nil) start := time.Now() - result, err := bus.Find("ParentEvent", nil, &abxbus.FindOptions{Past: 5.0, Future: false}) + result, err := bus.FindEventName("ParentEvent", nil, &abxbus.FindOptions{Past: 5.0, Future: false}) if err != nil { t.Fatal(err) } @@ -227,17 +227,17 @@ func TestFindPastFloatReturnsImmediatelyWithoutWaiting(t *testing.T) { func TestOrChainWithoutWaitingFindsExisting(t *testing.T) { bus := abxbus.NewEventBus("DebounceOrChainExistingBus", nil) - bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) - original := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) + original := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) if _, err := original.Now(); err != nil { t.Fatal(err) } start := time.Now() - found, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID1 }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -257,12 +257,12 @@ func TestOrChainWithoutWaitingFindsExisting(t *testing.T) { func TestOrChainWithoutWaitingDispatchesWhenNoMatch(t *testing.T) { bus := abxbus.NewEventBus("DebounceOrChainNoMatchBus", nil) - bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) start := time.Now() - found, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID1 }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -282,12 +282,12 @@ func TestOrChainWithoutWaitingDispatchesWhenNoMatch(t *testing.T) { func TestOrChainMultipleSequentialLookups(t *testing.T) { bus := abxbus.NewEventBus("DebounceSequentialBus", nil) - bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) start := time.Now() - found1, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found1, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID1 }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -295,7 +295,7 @@ func TestOrChainMultipleSequentialLookups(t *testing.T) { } result1 := debounceEmitFallback(bus, "ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}, found1) - found2, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found2, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID1 }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -303,7 +303,7 @@ func TestOrChainMultipleSequentialLookups(t *testing.T) { } result2 := debounceEmitFallback(bus, "ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}, found2) - found3, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + found3, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == debounceTargetID2 }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { diff --git a/abxbus-go/tests/eventbus_dispatch_contextvars_test.go b/abxbus-go/tests/eventbus_dispatch_contextvars_test.go index 9ffa8918..97e1339d 100644 --- a/abxbus-go/tests/eventbus_dispatch_contextvars_test.go +++ b/abxbus-go/tests/eventbus_dispatch_contextvars_test.go @@ -13,13 +13,13 @@ func TestAwaitedDispatchPropagatesContextIntoHandlers(t *testing.T) { bus := abxbus.NewEventBus("ContextDispatchBus", nil) key := contextKey("request_id") seen := "" - bus.On("ContextEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ContextEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen, _ = ctx.Value(key).(string) return "ok", nil }, nil) ctx := context.WithValue(context.Background(), key, "req-123") - if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("ContextEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventNameWithContext(ctx, "ContextEvent", nil).Now(); err != nil { t.Fatal(err) } if seen != "req-123" { @@ -31,20 +31,20 @@ func TestAwaitedChildDispatchPropagatesHandlerContext(t *testing.T) { bus := abxbus.NewEventBus("ContextChildBus", nil) key := contextKey("trace_id") childSeen := "" - bus.On("ParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := event.Emit(abxbus.NewBaseEvent("ChildContextEvent", nil)) + bus.OnEventName("ParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := event.EmitEventName("ChildContextEvent", nil) if _, err := child.Now(); err != nil { return nil, err } return "parent", nil }, nil) - bus.On("ChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childSeen, _ = ctx.Value(key).(string) return "child", nil }, nil) ctx := context.WithValue(context.Background(), key, "trace-456") - if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("ParentContextEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventNameWithContext(ctx, "ParentContextEvent", nil).Now(); err != nil { t.Fatal(err) } if childSeen != "trace-456" { @@ -59,20 +59,20 @@ func TestWaitChildDispatchPreservesHandlerContext(t *testing.T) { }) key := contextKey("event_completed_trace_id") childSeen := "" - bus.On("EventCompletedParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := event.Emit(abxbus.NewBaseEvent("EventCompletedChildContextEvent", nil)) + bus.OnEventName("EventCompletedParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := event.EmitEventName("EventCompletedChildContextEvent", nil) if _, err := child.Wait(); err != nil { return nil, err } return "parent", nil }, nil) - bus.On("EventCompletedChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("EventCompletedChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childSeen, _ = ctx.Value(key).(string) return "child", nil }, nil) ctx := context.WithValue(context.Background(), key, "trace-789") - if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("EventCompletedParentContextEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventNameWithContext(ctx, "EventCompletedParentContextEvent", nil).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 diff --git a/abxbus-go/tests/eventbus_dispatch_defaults_test.go b/abxbus-go/tests/eventbus_dispatch_defaults_test.go index 602b7ab3..3ffdb7b3 100644 --- a/abxbus-go/tests/eventbus_dispatch_defaults_test.go +++ b/abxbus-go/tests/eventbus_dispatch_defaults_test.go @@ -34,11 +34,11 @@ func TestEventConcurrencyRemainsUnsetOnDispatchAndResolvesDuringProcessing(t *te EventConcurrency: abxbus.EventConcurrencyParallel, }) defer bus.Destroy() - bus.On("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - implicit := bus.Emit(abxbus.NewBaseEvent("PropagationEvent", nil)) + implicit := bus.EmitEventName("PropagationEvent", nil) explicitNone := abxbus.NewBaseEvent("PropagationEvent", nil) explicitNone.EventConcurrency = "" explicitNone = bus.Emit(explicitNone) @@ -65,7 +65,7 @@ func TestEventConcurrencyClassOverrideBeatsBusDefault(t *testing.T) { EventConcurrency: abxbus.EventConcurrencyParallel, }) defer bus.Destroy() - bus.On("ConcurrencyOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ConcurrencyOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -108,11 +108,11 @@ func TestHandlerDefaultsRemainUnsetOnDispatchAndResolveDuringProcessing(t *testi EventHandlerCompletion: abxbus.EventHandlerCompletionFirst, }) defer bus.Destroy() - bus.On("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - implicit := bus.Emit(abxbus.NewBaseEvent("PropagationEvent", nil)) + implicit := bus.EmitEventName("PropagationEvent", nil) explicitNone := abxbus.NewBaseEvent("PropagationEvent", nil) explicitNone.EventHandlerConcurrency = "" explicitNone.EventHandlerCompletion = "" @@ -142,7 +142,7 @@ func TestHandlerClassOverrideBeatsBusDefault(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionFirst, }) defer bus.Destroy() - bus.On("HandlerOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("HandlerOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) diff --git a/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go b/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go index 7b38a2cc..9d617ea7 100644 --- a/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go +++ b/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go @@ -17,8 +17,8 @@ func TestQueueJumpProcessesChildInsideParentHandler(t *testing.T) { var capturedChild *abxbus.BaseEvent childProcessedBeforeParentReturn := false - bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - capturedChild = e.Emit(abxbus.NewBaseEvent("Child", nil)) + bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + capturedChild = e.EmitEventName("Child", nil) if _, err := capturedChild.Now(); err != nil { return nil, err } @@ -27,11 +27,11 @@ func TestQueueJumpProcessesChildInsideParentHandler(t *testing.T) { } return "parent", nil }, nil) - bus.On("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -82,17 +82,17 @@ func TestEventEmitWithoutAwaitTracksChildButDoesNotBlockParentCompletion(t *test releaseChild := make(chan struct{}) var capturedChild *abxbus.BaseEvent - bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - capturedChild = e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"mode": "unawaited"})) + bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + capturedChild = e.EmitEventName("Child", map[string]any{"mode": "unawaited"}) return "parent", nil }, nil) - bus.On("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { childStarted <- struct{}{} <-releaseChild return "child", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { close(releaseChild) t.Fatal(err) @@ -143,17 +143,17 @@ func TestBusEmitInsideHandlerIsUntrackedBackgroundEvent(t *testing.T) { releaseBg := make(chan struct{}) var background *abxbus.BaseEvent - bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - background = bus.Emit(abxbus.NewBaseEvent("Background", map[string]any{"mode": "untracked"})) + bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + background = bus.EmitEventName("Background", map[string]any{"mode": "untracked"}) return "parent", nil }, nil) - bus.On("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { bgStarted <- struct{}{} <-releaseBg return "background", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { close(releaseBg) t.Fatal(err) @@ -201,19 +201,19 @@ func TestAwaitedBusEmitInsideHandlerQueueJumpsButStaysUntrackedRootEvent(t *test var background *abxbus.BaseEvent backgroundCompletedBeforeParentReturn := false - bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - background = bus.Emit(abxbus.NewBaseEvent("Background", map[string]any{"mode": "awaited"})) + bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + background = bus.EmitEventName("Background", map[string]any{"mode": "awaited"}) if _, err := background.Now(); err != nil { return nil, err } backgroundCompletedBeforeParentReturn = background.EventStatus == "completed" return "parent", nil }, nil) - bus.On("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "background", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -246,21 +246,21 @@ func TestErroringParentHandlersStillTrackChildrenAndContinue(t *testing.T) { }) childEvents := []*abxbus.BaseEvent{} - bus.On("Parent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"source": "failing"})) + bus.OnEventName("Parent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := e.EmitEventName("Child", map[string]any{"source": "failing"}) childEvents = append(childEvents, child) return nil, errors.New("expected parent handler failure") }, nil) - bus.On("Parent", "success", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"source": "success"})) + bus.OnEventName("Parent", "success", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := e.EmitEventName("Child", map[string]any{"source": "success"}) childEvents = append(childEvents, child) return "success", nil }, nil) - bus.On("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -285,19 +285,19 @@ func TestEventChildrenTrackDirectAndNestedDescendants(t *testing.T) { var child *abxbus.BaseEvent var grandchild *abxbus.BaseEvent - bus.On("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child = e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"level": 1})) + bus.OnEventName("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child = e.EmitEventName("Child", map[string]any{"level": 1}) return "parent", nil }, nil) - bus.On("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - grandchild = e.Emit(abxbus.NewBaseEvent("Grandchild", map[string]any{"level": 2})) + bus.OnEventName("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + grandchild = e.EmitEventName("Grandchild", map[string]any{"level": 2}) return "child", nil }, nil) - bus.On("Grandchild", "grandchild", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Grandchild", "grandchild", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "grandchild", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_error_handling_test.go b/abxbus-go/tests/eventbus_error_handling_test.go index 32ba0635..0c0d8b3b 100644 --- a/abxbus-go/tests/eventbus_error_handling_test.go +++ b/abxbus-go/tests/eventbus_error_handling_test.go @@ -10,10 +10,10 @@ import ( func TestEventResultPropagatesHandlerError(t *testing.T) { bus := abxbus.NewEventBus("ErrBus", nil) - bus.On("ErrEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ErrEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - e := bus.Emit(abxbus.NewBaseEvent("ErrEvent", nil)) + e := bus.EmitEventName("ErrEvent", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -25,11 +25,11 @@ func TestEventResultPropagatesHandlerError(t *testing.T) { func TestNowRaiseIfAnyOptions(t *testing.T) { bus := abxbus.NewEventBus("NowRaiseIfAnyBus", nil) - bus.On("NowErrorEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NowErrorEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - event := bus.Emit(abxbus.NewBaseEvent("NowErrorEvent", nil)) + event := bus.EmitEventName("NowErrorEvent", nil) if _, err := event.Now(); err != nil { t.Fatalf("Now should wait for completion without surfacing handler errors, got %v", err) } @@ -43,13 +43,13 @@ func TestNowRaiseIfAnyOptions(t *testing.T) { func TestEventCompletesWhenOneHandlerErrorsAndAnotherSucceeds(t *testing.T) { bus := abxbus.NewEventBus("ErrMixedBus", &abxbus.EventBusOptions{EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel}) - bus.On("MixedEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MixedEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.On("MixedEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MixedEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - e := bus.Emit(abxbus.NewBaseEvent("MixedEvent", nil)) + e := bus.EmitEventName("MixedEvent", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -93,16 +93,16 @@ func TestSerialHandlerErrorDoesNotPreventLaterHandlers(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) calls := []string{} - bus.On("MixedEvent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MixedEvent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "failing") return nil, errors.New("expected failure") }, nil) - bus.On("MixedEvent", "working", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MixedEvent", "working", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "working") return "worked", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("MixedEvent", nil)) + event := bus.EmitEventName("MixedEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_find_test.go b/abxbus-go/tests/eventbus_find_test.go index 734f1e85..b9fef837 100644 --- a/abxbus-go/tests/eventbus_find_test.go +++ b/abxbus-go/tests/eventbus_find_test.go @@ -8,14 +8,19 @@ import ( abxbus "github.com/ArchiveBox/abxbus/abxbus-go/v2" ) +type TypedFindEvent struct { + RequestID string `json:"request_id"` + Count int `json:"count"` +} + func TestFindHistoryAndFuture(t *testing.T) { bus := abxbus.NewEventBus("FindBus", nil) - seed := bus.Emit(abxbus.NewBaseEvent("ResponseEvent", map[string]any{"request_id": "abc"})) + seed := bus.EmitEventName("ResponseEvent", map[string]any{"request_id": "abc"}) if _, err := seed.Now(); err != nil { t.Fatal(err) } - match, err := bus.Find("ResponseEvent", func(e *abxbus.BaseEvent) bool { + match, err := bus.FindEventName("ResponseEvent", func(e *abxbus.BaseEvent) bool { return e.Payload["request_id"] == "abc" }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -27,9 +32,9 @@ func TestFindHistoryAndFuture(t *testing.T) { go func() { time.Sleep(20 * time.Millisecond) - bus.Emit(abxbus.NewBaseEvent("FutureEvent", map[string]any{"request_id": "future"})) + bus.EmitEventName("FutureEvent", map[string]any{"request_id": "future"}) }() - future, err := bus.Find("FutureEvent", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) + future, err := bus.FindEventName("FutureEvent", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { t.Fatal(err) } @@ -38,9 +43,52 @@ func TestFindHistoryAndFuture(t *testing.T) { } } +func TestFindAndFilterDefaultToTypedEvents(t *testing.T) { + bus := abxbus.NewEventBus("TypedFindFilterBus", nil) + first := bus.Emit(TypedFindEvent{RequestID: "one", Count: 1}) + second := bus.Emit(TypedFindEvent{RequestID: "two", Count: 2}) + if _, err := first.Now(); err != nil { + t.Fatal(err) + } + if _, err := second.Now(); err != nil { + t.Fatal(err) + } + + found, err := bus.Find(TypedFindEvent{}, func(payload TypedFindEvent) bool { + return payload.RequestID == "two" + }, &abxbus.FindOptions{Past: true, Future: false}) + if err != nil { + t.Fatal(err) + } + if found == nil || found.EventID != second.EventID { + t.Fatalf("expected typed find to match second event, got %#v", found) + } + + matches, err := bus.Filter(TypedFindEvent{}, func(payload TypedFindEvent) bool { + return payload.Count >= 1 + }, &abxbus.FilterOptions{Past: true, Future: false}) + if err != nil { + t.Fatal(err) + } + if len(matches) != 2 || matches[0].EventID != second.EventID || matches[1].EventID != first.EventID { + t.Fatalf("expected typed filter to return newest-first matches, got %#v", matches) + } +} + +func TestEmitEventNameCoversRawStringEmission(t *testing.T) { + bus := abxbus.NewEventBus("EmitEventNameBus", nil) + event := bus.EmitEventName("RawStringEvent", map[string]any{"ok": true}) + if _, err := event.Now(); err != nil { + t.Fatal(err) + } + if event.EventType != "RawStringEvent" || event.Payload["ok"] != true { + t.Fatalf("unexpected raw event emission: %#v", event) + } +} + func TestFindReturnsNilWhenNoMatch(t *testing.T) { bus := abxbus.NewEventBus("FindNilBus", nil) - match, err := bus.Find("MissingEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + match, err := bus.FindEventName("MissingEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -51,11 +99,11 @@ func TestFindReturnsNilWhenNoMatch(t *testing.T) { func TestFindDefaultPastOnlyNoFutureWait(t *testing.T) { bus := abxbus.NewEventBus("FindDefaultBus", nil) - seed := bus.Emit(abxbus.NewBaseEvent("DefaultEvent", nil)) + seed := bus.EmitEventName("DefaultEvent", nil) if _, err := seed.Now(); err != nil { t.Fatal(err) } - match, err := bus.Find("DefaultEvent", nil, nil) + match, err := bus.FindEventName("DefaultEvent", nil, nil) if err != nil { t.Fatal(err) } @@ -66,12 +114,12 @@ func TestFindDefaultPastOnlyNoFutureWait(t *testing.T) { func TestFindFutureIgnoresPastEvents(t *testing.T) { bus := abxbus.NewEventBus("FindFutureIgnoresPastBus", nil) - prior := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + prior := bus.EmitEventName("ParentEvent", nil) if _, err := prior.Now(); err != nil { t.Fatal(err) } - found, err := bus.Find("ParentEvent", nil, &abxbus.FindOptions{Past: false, Future: 0.03}) + found, err := bus.FindEventName("ParentEvent", nil, &abxbus.FindOptions{Past: false, Future: 0.03}) if err != nil { t.Fatal(err) } @@ -83,7 +131,7 @@ func TestFindFutureIgnoresPastEvents(t *testing.T) { func TestFindPastFalseFutureFalseReturnsNilImmediately(t *testing.T) { bus := abxbus.NewEventBus("FindNeitherBus", nil) start := time.Now() - found, err := bus.Find("ParentEvent", nil, &abxbus.FindOptions{Past: false, Future: false}) + found, err := bus.FindEventName("ParentEvent", nil, &abxbus.FindOptions{Past: false, Future: false}) if err != nil { t.Fatal(err) } @@ -97,14 +145,14 @@ func TestFindPastFalseFutureFalseReturnsNilImmediately(t *testing.T) { func TestFindPastAndFutureWindowsAreIndependent(t *testing.T) { bus := abxbus.NewEventBus("FindWindowIndependentBus", nil) - oldEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + oldEvent := bus.EmitEventName("ParentEvent", nil) if _, err := oldEvent.Now(); err != nil { t.Fatal(err) } time.Sleep(120 * time.Millisecond) start := time.Now() - found, err := bus.Find("ParentEvent", nil, &abxbus.FindOptions{Past: 0.03, Future: 0.03}) + found, err := bus.FindEventName("ParentEvent", nil, &abxbus.FindOptions{Past: 0.03, Future: 0.03}) if err != nil { t.Fatal(err) } @@ -130,7 +178,7 @@ func TestFindPastWindowAndEqualsFiltering(t *testing.T) { t.Fatal(err) } - recent, err := bus.Find("WindowEvent", nil, &abxbus.FindOptions{Past: 0.5, Future: false, Equals: map[string]any{"event_type": "WindowEvent", "event_status": "completed"}}) + recent, err := bus.FindEventName("WindowEvent", nil, &abxbus.FindOptions{Past: 0.5, Future: false, Equals: map[string]any{"event_type": "WindowEvent", "event_status": "completed"}}) if err != nil { t.Fatal(err) } @@ -138,7 +186,7 @@ func TestFindPastWindowAndEqualsFiltering(t *testing.T) { t.Fatalf("expected past-window filter to return recent event, got %#v", recent) } - equalsMatch, err := bus.Find("WindowEvent", nil, &abxbus.FindOptions{Past: true, Future: false, Equals: map[string]any{"request_id": "new"}}) + equalsMatch, err := bus.FindEventName("WindowEvent", nil, &abxbus.FindOptions{Past: true, Future: false, Equals: map[string]any{"request_id": "new"}}) if err != nil { t.Fatal(err) } @@ -161,7 +209,7 @@ func TestFindSupportsMetadataAndPayloadEqualityFilters(t *testing.T) { } } - foundA, err := bus.Find("FieldFilterEvent", nil, &abxbus.FindOptions{ + foundA, err := bus.FindEventName("FieldFilterEvent", nil, &abxbus.FindOptions{ Past: true, Future: false, Equals: map[string]any{ @@ -179,7 +227,7 @@ func TestFindSupportsMetadataAndPayloadEqualityFilters(t *testing.T) { t.Fatalf("expected metadata and payload filters to match event A, got %#v", foundA) } - mismatch, err := bus.Find("FieldFilterEvent", nil, &abxbus.FindOptions{ + mismatch, err := bus.FindEventName("FieldFilterEvent", nil, &abxbus.FindOptions{ Past: true, Future: false, Equals: map[string]any{ @@ -194,7 +242,7 @@ func TestFindSupportsMetadataAndPayloadEqualityFilters(t *testing.T) { t.Fatalf("expected mismatched metadata filters to return nil, got %#v", mismatch) } - foundPayload, err := bus.Find("FieldFilterEvent", nil, &abxbus.FindOptions{ + foundPayload, err := bus.FindEventName("FieldFilterEvent", nil, &abxbus.FindOptions{ Past: true, Future: false, Equals: map[string]any{ @@ -213,8 +261,8 @@ func TestFindSupportsMetadataAndPayloadEqualityFilters(t *testing.T) { func TestFindWherePredicateAndBusScopedHistory(t *testing.T) { busA := abxbus.NewEventBus("FindBusA", nil) busB := abxbus.NewEventBus("FindBusB", nil) - matchA := busA.Emit(abxbus.NewBaseEvent("ScopedEvent", map[string]any{"source": "A", "value": 1})) - matchB := busB.Emit(abxbus.NewBaseEvent("ScopedEvent", map[string]any{"source": "B", "value": 2})) + matchA := busA.EmitEventName("ScopedEvent", map[string]any{"source": "A", "value": 1}) + matchB := busB.EmitEventName("ScopedEvent", map[string]any{"source": "B", "value": 2}) if _, err := matchA.Now(); err != nil { t.Fatal(err) } @@ -222,7 +270,7 @@ func TestFindWherePredicateAndBusScopedHistory(t *testing.T) { t.Fatal(err) } - foundA, err := busA.Find("ScopedEvent", func(event *abxbus.BaseEvent) bool { + foundA, err := busA.FindEventName("ScopedEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["source"] == "A" && event.Payload["value"] == 1 }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -232,7 +280,7 @@ func TestFindWherePredicateAndBusScopedHistory(t *testing.T) { t.Fatalf("expected bus A to find only its own event, got %#v", foundA) } - foundB, err := busB.Find("ScopedEvent", func(event *abxbus.BaseEvent) bool { + foundB, err := busB.FindEventName("ScopedEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["source"] == "B" }, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { @@ -246,7 +294,7 @@ func TestFindWherePredicateAndBusScopedHistory(t *testing.T) { func TestFindChildOfFilteringAndLineageTraversal(t *testing.T) { bus := abxbus.NewEventBus("FindChildBus", nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -281,7 +329,7 @@ func TestFindChildOfFilteringAndLineageTraversal(t *testing.T) { t.Fatal("event should not be child of itself") } - found, err := bus.Find("Grandchild", nil, &abxbus.FindOptions{Past: true, Future: false, ChildOf: parent}) + found, err := bus.FindEventName("Grandchild", nil, &abxbus.FindOptions{Past: true, Future: false, ChildOf: parent}) if err != nil { t.Fatal(err) } @@ -294,13 +342,13 @@ func TestFindCanSeeInProgressEventInHistory(t *testing.T) { bus := abxbus.NewEventBus("FindInProgressBus", nil) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.On("SlowFindEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SlowFindEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return "ok", nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("SlowFindEvent", nil)) + e := bus.EmitEventName("SlowFindEvent", nil) select { case <-started: case <-time.After(2 * time.Second): @@ -308,7 +356,7 @@ func TestFindCanSeeInProgressEventInHistory(t *testing.T) { t.Fatal("timed out waiting for slow handler start") } - match, err := bus.Find("SlowFindEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + match, err := bus.FindEventName("SlowFindEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { close(release) t.Fatal(err) @@ -329,7 +377,7 @@ func TestFindFutureIgnoresAlreadyDispatchedInFlightEventsWhenPastFalse(t *testin t.Cleanup(bus.Destroy) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.On("FutureInflightEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("FutureInflightEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} select { case <-release: @@ -339,7 +387,7 @@ func TestFindFutureIgnoresAlreadyDispatchedInFlightEventsWhenPastFalse(t *testin return "ok", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("FutureInflightEvent", nil)) + event := bus.EmitEventName("FutureInflightEvent", nil) select { case <-started: case <-time.After(2 * time.Second): @@ -347,7 +395,7 @@ func TestFindFutureIgnoresAlreadyDispatchedInFlightEventsWhenPastFalse(t *testin t.Fatal("timed out waiting for in-flight event") } - match, err := bus.Find("FutureInflightEvent", nil, &abxbus.FindOptions{Past: false, Future: 0.03}) + match, err := bus.FindEventName("FutureInflightEvent", nil, &abxbus.FindOptions{Past: false, Future: 0.03}) close(release) if err != nil { t.Fatal(err) @@ -365,7 +413,7 @@ func TestFindFutureResolvesOnDispatchBeforeHandlersComplete(t *testing.T) { t.Cleanup(bus.Destroy) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.On("DispatchVisibleEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("DispatchVisibleEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} select { case <-release: @@ -377,9 +425,9 @@ func TestFindFutureResolvesOnDispatchBeforeHandlersComplete(t *testing.T) { go func() { time.Sleep(20 * time.Millisecond) - bus.Emit(abxbus.NewBaseEvent("DispatchVisibleEvent", nil)) + bus.EmitEventName("DispatchVisibleEvent", nil) }() - match, err := bus.Find("DispatchVisibleEvent", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) + match, err := bus.FindEventName("DispatchVisibleEvent", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { close(release) t.Fatal(err) @@ -412,7 +460,7 @@ func TestMultipleConcurrentFutureFindWaitersResolveCorrectEvents(t *testing.T) { errs := make(chan error, 2) go func() { - event, err := bus.Find("ConcurrentFindA", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) + event, err := bus.FindEventName("ConcurrentFindA", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { errs <- err return @@ -420,7 +468,7 @@ func TestMultipleConcurrentFutureFindWaitersResolveCorrectEvents(t *testing.T) { resultA <- event }() go func() { - event, err := bus.Find("ConcurrentFindB", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) + event, err := bus.FindEventName("ConcurrentFindB", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { errs <- err return @@ -429,8 +477,8 @@ func TestMultipleConcurrentFutureFindWaitersResolveCorrectEvents(t *testing.T) { }() time.Sleep(20 * time.Millisecond) - eventB := bus.Emit(abxbus.NewBaseEvent("ConcurrentFindB", nil)) - eventA := bus.Emit(abxbus.NewBaseEvent("ConcurrentFindA", nil)) + eventB := bus.EmitEventName("ConcurrentFindB", nil) + eventA := bus.EmitEventName("ConcurrentFindA", nil) select { case err := <-errs: @@ -464,18 +512,18 @@ func TestMultipleConcurrentFutureFindWaitersResolveCorrectEvents(t *testing.T) { func TestMaxHistorySizeZeroDisablesPastSearchButFutureFindStillResolves(t *testing.T) { zeroHistorySize := 0 bus := abxbus.NewEventBus("FindZeroHistoryBus", &abxbus.EventBusOptions{MaxHistorySize: &zeroHistorySize}) - bus.On("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok:" + event.Payload["value"].(string), nil }, nil) - first := bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "first"})) + first := bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "first"}) if _, err := first.Now(); err != nil { t.Fatal(err) } if bus.EventHistory.Size() != 0 { t.Fatalf("zero history should drop completed event, got size=%d", bus.EventHistory.Size()) } - past, err := bus.Find("ZeroHistoryEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + past, err := bus.FindEventName("ZeroHistoryEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -485,9 +533,9 @@ func TestMaxHistorySizeZeroDisablesPastSearchButFutureFindStillResolves(t *testi go func() { time.Sleep(20 * time.Millisecond) - bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "future"})) + bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "future"}) }() - future, err := bus.Find("ZeroHistoryEvent", func(event *abxbus.BaseEvent) bool { + future, err := bus.FindEventName("ZeroHistoryEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["value"] == "future" }, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { @@ -506,8 +554,8 @@ func TestMaxHistorySizeZeroDisablesPastSearchButFutureFindStillResolves(t *testi func TestFindReturnsFirstFilterResult(t *testing.T) { bus := abxbus.NewEventBus("FindFilterFirstBus", nil) - first := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) - second := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + first := bus.EmitEventName("ParentEvent", nil) + second := bus.EmitEventName("ParentEvent", nil) if _, err := first.Now(); err != nil { t.Fatal(err) } @@ -515,12 +563,12 @@ func TestFindReturnsFirstFilterResult(t *testing.T) { t.Fatal(err) } - found, err := bus.Find("ParentEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + found, err := bus.FindEventName("ParentEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } limit := 1 - filtered, err := bus.Filter("ParentEvent", nil, &abxbus.FilterOptions{Past: true, Future: false, Limit: &limit}) + filtered, err := bus.FilterEventName("ParentEvent", nil, &abxbus.FilterOptions{Past: true, Future: false, Limit: &limit}) if err != nil { t.Fatal(err) } @@ -534,8 +582,8 @@ func TestFindReturnsFirstFilterResult(t *testing.T) { func TestFindSupportsPayloadFieldNamedLimitViaEquals(t *testing.T) { bus := abxbus.NewEventBus("FindLimitFieldBus", nil) - noMatch := bus.Emit(abxbus.NewBaseEvent("LimitFieldEvent", map[string]any{"limit": 3})) - target := bus.Emit(abxbus.NewBaseEvent("LimitFieldEvent", map[string]any{"limit": 5})) + noMatch := bus.EmitEventName("LimitFieldEvent", map[string]any{"limit": 3}) + target := bus.EmitEventName("LimitFieldEvent", map[string]any{"limit": 5}) if _, err := noMatch.Now(); err != nil { t.Fatal(err) } @@ -543,7 +591,7 @@ func TestFindSupportsPayloadFieldNamedLimitViaEquals(t *testing.T) { t.Fatal(err) } - match, err := bus.Find("LimitFieldEvent", nil, &abxbus.FindOptions{ + match, err := bus.FindEventName("LimitFieldEvent", nil, &abxbus.FindOptions{ Past: true, Future: false, Equals: map[string]any{"limit": 5}, @@ -564,7 +612,7 @@ func TestFilterLimitZeroAndNegativeReturnImmediatelyWithoutFutureWait(t *testing t.Cleanup(bus.Destroy) for _, limit := range []int{0, -1} { start := time.Now() - matches, err := bus.Filter("NeverDispatched", nil, &abxbus.FilterOptions{Past: false, Future: 1.0, Limit: &limit}) + matches, err := bus.FilterEventName("NeverDispatched", nil, &abxbus.FilterOptions{Past: false, Future: 1.0, Limit: &limit}) if err != nil { t.Fatal(err) } @@ -581,7 +629,7 @@ func TestFilterFutureOnlyTimesOutToEmptyList(t *testing.T) { bus := abxbus.NewEventBus("FilterFutureTimeoutBus", nil) t.Cleanup(bus.Destroy) start := time.Now() - matches, err := bus.Filter("MissingFutureFilterEvent", nil, &abxbus.FilterOptions{Past: false, Future: 0.03}) + matches, err := bus.FilterEventName("MissingFutureFilterEvent", nil, &abxbus.FilterOptions{Past: false, Future: 0.03}) if err != nil { t.Fatal(err) } @@ -596,7 +644,7 @@ func TestFilterFutureOnlyTimesOutToEmptyList(t *testing.T) { func TestFilterReturnsEmptyArrayWhenNoMatches(t *testing.T) { bus := abxbus.NewEventBus("FilterEmptyBus", nil) - matches, err := bus.Filter("ParentEvent", nil, &abxbus.FilterOptions{Past: true, Future: false}) + matches, err := bus.FilterEventName("ParentEvent", nil, &abxbus.FilterOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -607,9 +655,9 @@ func TestFilterReturnsEmptyArrayWhenNoMatches(t *testing.T) { func TestFilterReturnsPastMatchesNewestFirstAndRespectsLimit(t *testing.T) { bus := abxbus.NewEventBus("FilterPastBus", nil) - first := bus.Emit(abxbus.NewBaseEvent("Work", map[string]any{"n": 1})) - second := bus.Emit(abxbus.NewBaseEvent("Work", map[string]any{"n": 2})) - third := bus.Emit(abxbus.NewBaseEvent("Work", map[string]any{"n": 3})) + first := bus.EmitEventName("Work", map[string]any{"n": 1}) + second := bus.EmitEventName("Work", map[string]any{"n": 2}) + third := bus.EmitEventName("Work", map[string]any{"n": 3}) for _, event := range []*abxbus.BaseEvent{first, second, third} { if _, err := event.Now(); err != nil { t.Fatal(err) @@ -617,7 +665,7 @@ func TestFilterReturnsPastMatchesNewestFirstAndRespectsLimit(t *testing.T) { } limit := 2 - matches, err := bus.Filter("Work", nil, &abxbus.FilterOptions{Past: true, Future: false, Limit: &limit}) + matches, err := bus.FilterEventName("Work", nil, &abxbus.FilterOptions{Past: true, Future: false, Limit: &limit}) if err != nil { t.Fatal(err) } @@ -628,16 +676,16 @@ func TestFilterReturnsPastMatchesNewestFirstAndRespectsLimit(t *testing.T) { func TestFilterRespectsWherePredicateNewestFirst(t *testing.T) { bus := abxbus.NewEventBus("FilterWhereBus", nil) - first := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": "same"})) - other := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": "other"})) - second := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": "same"})) + first := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": "same"}) + other := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": "other"}) + second := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": "same"}) for _, event := range []*abxbus.BaseEvent{first, other, second} { if _, err := event.Now(); err != nil { t.Fatal(err) } } - matches, err := bus.Filter("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { + matches, err := bus.FilterEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["target_id"] == "same" }, &abxbus.FilterOptions{Past: true, Future: false}) if err != nil { @@ -650,8 +698,8 @@ func TestFilterRespectsWherePredicateNewestFirst(t *testing.T) { func TestFilterWildcardMatchesAllEventTypesNewestFirst(t *testing.T) { bus := abxbus.NewEventBus("FilterWildcardBus", nil) - userEvent := bus.Emit(abxbus.NewBaseEvent("UserActionEvent", map[string]any{"action": "login"})) - systemEvent := bus.Emit(abxbus.NewBaseEvent("SystemEvent", nil)) + userEvent := bus.EmitEventName("UserActionEvent", map[string]any{"action": "login"}) + systemEvent := bus.EmitEventName("SystemEvent", nil) if _, err := userEvent.Now(); err != nil { t.Fatal(err) } @@ -659,7 +707,7 @@ func TestFilterWildcardMatchesAllEventTypesNewestFirst(t *testing.T) { t.Fatal(err) } - matches, err := bus.Filter("*", nil, &abxbus.FilterOptions{Past: true, Future: false}) + matches, err := bus.FilterEventName("*", nil, &abxbus.FilterOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -670,17 +718,17 @@ func TestFilterWildcardMatchesAllEventTypesNewestFirst(t *testing.T) { func TestFilterPastWindowFiltersByAge(t *testing.T) { bus := abxbus.NewEventBus("FilterPastWindowBus", nil) - oldEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + oldEvent := bus.EmitEventName("ParentEvent", nil) if _, err := oldEvent.Now(); err != nil { t.Fatal(err) } time.Sleep(120 * time.Millisecond) - newEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + newEvent := bus.EmitEventName("ParentEvent", nil) if _, err := newEvent.Now(); err != nil { t.Fatal(err) } - matches, err := bus.Filter("ParentEvent", nil, &abxbus.FilterOptions{Past: 0.1, Future: false}) + matches, err := bus.FilterEventName("ParentEvent", nil, &abxbus.FilterOptions{Past: 0.1, Future: false}) if err != nil { t.Fatal(err) } @@ -691,16 +739,16 @@ func TestFilterPastWindowFiltersByAge(t *testing.T) { func TestFilterFutureAppendsMatchAfterPastResults(t *testing.T) { bus := abxbus.NewEventBus("FilterFutureAppendBus", nil) - pastEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + pastEvent := bus.EmitEventName("ParentEvent", nil) if _, err := pastEvent.Now(); err != nil { t.Fatal(err) } go func() { time.Sleep(20 * time.Millisecond) - bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + bus.EmitEventName("ParentEvent", nil) }() - matches, err := bus.Filter("ParentEvent", nil, &abxbus.FilterOptions{Past: true, Future: 0.5}) + matches, err := bus.FilterEventName("ParentEvent", nil, &abxbus.FilterOptions{Past: true, Future: 0.5}) if err != nil { t.Fatal(err) } @@ -714,7 +762,7 @@ func TestFilterFutureAppendsMatchAfterPastResults(t *testing.T) { func TestFilterSupportsWhereEqualsWildcardChildAndFuture(t *testing.T) { bus := abxbus.NewEventBus("FilterOptionsBus", nil) - parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) + parent := bus.EmitEventName("Parent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -724,9 +772,9 @@ func TestFilterSupportsWhereEqualsWildcardChildAndFuture(t *testing.T) { if _, err := child.Now(); err != nil { t.Fatal(err) } - bus.Emit(abxbus.NewBaseEvent("Other", map[string]any{"kind": "target"})) + bus.EmitEventName("Other", map[string]any{"kind": "target"}) - childMatches, err := bus.Filter("*", func(event *abxbus.BaseEvent) bool { + childMatches, err := bus.FilterEventName("*", func(event *abxbus.BaseEvent) bool { return event.Payload["kind"] == "target" }, &abxbus.FilterOptions{Past: true, Future: false, ChildOf: parent, Equals: map[string]any{"kind": "target"}}) if err != nil { @@ -738,9 +786,9 @@ func TestFilterSupportsWhereEqualsWildcardChildAndFuture(t *testing.T) { go func() { time.Sleep(20 * time.Millisecond) - bus.Emit(abxbus.NewBaseEvent("FutureWork", map[string]any{"kind": "future"})) + bus.EmitEventName("FutureWork", map[string]any{"kind": "future"}) }() - futureMatches, err := bus.Filter("FutureWork", nil, &abxbus.FilterOptions{ + futureMatches, err := bus.FilterEventName("FutureWork", nil, &abxbus.FilterOptions{ Past: false, Future: 1.0, Equals: map[string]any{"kind": "future"}, @@ -752,7 +800,7 @@ func TestFilterSupportsWhereEqualsWildcardChildAndFuture(t *testing.T) { t.Fatalf("expected one future match, got %#v", futureMatches) } - none, err := bus.Filter("Missing", nil, &abxbus.FilterOptions{Past: false, Future: false}) + none, err := bus.FilterEventName("Missing", nil, &abxbus.FilterOptions{Past: false, Future: false}) if err != nil { t.Fatal(err) } @@ -775,7 +823,7 @@ func TestFilterSupportsMetadataEqualityAndFutureLimitShortCircuit(t *testing.T) } } - matches, err := bus.Filter("NumberedEvent", nil, &abxbus.FilterOptions{ + matches, err := bus.FilterEventName("NumberedEvent", nil, &abxbus.FilterOptions{ Past: true, Future: false, Equals: map[string]any{ @@ -792,7 +840,7 @@ func TestFilterSupportsMetadataEqualityAndFutureLimitShortCircuit(t *testing.T) limit := 1 start := time.Now() - limited, err := bus.Filter("NumberedEvent", nil, &abxbus.FilterOptions{Past: true, Future: 2.0, Limit: &limit}) + limited, err := bus.FilterEventName("NumberedEvent", nil, &abxbus.FilterOptions{Past: true, Future: 2.0, Limit: &limit}) if err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_forwarding_test.go b/abxbus-go/tests/eventbus_forwarding_test.go index db2d4ae6..d003ef85 100644 --- a/abxbus-go/tests/eventbus_forwarding_test.go +++ b/abxbus-go/tests/eventbus_forwarding_test.go @@ -21,28 +21,28 @@ func TestEventsForwardBetweenBusesWithoutDuplication(t *testing.T) { seenA := []string{} seenB := []string{} seenC := []string{} - busA.On("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenA = append(seenA, event.EventID) return "a", nil }, nil) - busB.On("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenB = append(seenB, event.EventID) return "b", nil }, nil) - busC.On("PingEvent", "seen_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busC.OnEventName("PingEvent", "seen_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenC = append(seenC, event.EventID) return "c", nil }, nil) - busA.On("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busB.Emit(event) return nil, nil }, nil) - busB.On("*", "forward_to_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("*", "forward_to_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busC.Emit(event) return nil, nil }, nil) - event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 1})) + event := busA.EmitEventName("PingEvent", map[string]any{"value": 1}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -73,28 +73,28 @@ func TestTreeLevelHierarchyBubbling(t *testing.T) { seenParent := []string{} seenChild := []string{} seenSubchild := []string{} - parentBus.On("PingEvent", "parent_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parentBus.OnEventName("PingEvent", "parent_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenParent = append(seenParent, event.EventID) return nil, nil }, nil) - childBus.On("PingEvent", "child_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + childBus.OnEventName("PingEvent", "child_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenChild = append(seenChild, event.EventID) return nil, nil }, nil) - subchildBus.On("PingEvent", "subchild_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + subchildBus.OnEventName("PingEvent", "subchild_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenSubchild = append(seenSubchild, event.EventID) return nil, nil }, nil) - childBus.On("*", "forward_to_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + childBus.OnEventName("*", "forward_to_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { parentBus.Emit(event) return nil, nil }, nil) - subchildBus.On("*", "forward_to_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + subchildBus.OnEventName("*", "forward_to_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childBus.Emit(event) return nil, nil }, nil) - bottom := subchildBus.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 1})) + bottom := subchildBus.EmitEventName("PingEvent", map[string]any{"value": 1}) if _, err := bottom.Now(); err != nil { t.Fatal(err) } @@ -111,7 +111,7 @@ func TestTreeLevelHierarchyBubbling(t *testing.T) { } seenParent, seenChild, seenSubchild = []string{}, []string{}, []string{} - middle := childBus.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 2})) + middle := childBus.EmitEventName("PingEvent", map[string]any{"value": 2}) if _, err := middle.Now(); err != nil { t.Fatal(err) } @@ -134,20 +134,20 @@ func TestForwardingDisambiguatesBusesThatShareTheSameName(t *testing.T) { seenA := []string{} seenB := []string{} - busA.On("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenA = append(seenA, event.EventID) return "a", nil }, nil) - busB.On("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenB = append(seenB, event.EventID) return "b", nil }, nil) - busA.On("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busB.Emit(event) return nil, nil }, nil) - event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 99})) + event := busA.EmitEventName("PingEvent", map[string]any{"value": 99}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -181,31 +181,31 @@ func TestAwaitEventNowWaitsForHandlersOnForwardedBuses(t *testing.T) { completionLog = append(completionLog, value) } - busA.On("PingEvent", "a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("PingEvent", "a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) record("A") return "a", nil }, nil) - busB.On("PingEvent", "b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("PingEvent", "b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) record("B") return "b", nil }, nil) - busC.On("PingEvent", "c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busC.OnEventName("PingEvent", "c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(50 * time.Millisecond) record("C") return "c", nil }, nil) - busA.On("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busB.Emit(event) return nil, nil }, nil) - busB.On("*", "forward_to_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("*", "forward_to_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busC.Emit(event) return nil, nil }, nil) - event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 2})) + event := busA.EmitEventName("PingEvent", map[string]any{"value": 2}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -234,7 +234,7 @@ func TestCircularForwardingFromFirstPeerDoesNotLoop(t *testing.T) { defer peer3.Destroy() seen1, seen2, seen3 := registerCycle(t, peer1, peer2, peer3) - event := peer1.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 42})) + event := peer1.EmitEventName("PingEvent", map[string]any{"value": 42}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -260,14 +260,14 @@ func TestCircularForwardingFromMiddlePeerDoesNotLoop(t *testing.T) { defer peer3.Destroy() seen1, seen2, seen3 := registerCycle(t, peer1, peer2, peer3) - warmup := peer1.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 42})) + warmup := peer1.EmitEventName("PingEvent", map[string]any{"value": 42}) if _, err := warmup.Now(); err != nil { t.Fatal(err) } waitAllIdle(t, peer1, peer2, peer3) *seen1, *seen2, *seen3 = []string{}, []string{}, []string{} - event := peer2.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 99})) + event := peer2.EmitEventName("PingEvent", map[string]any{"value": 99}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -295,23 +295,23 @@ func TestAwaitEventNowWaitsWhenForwardingHandlerIsAsyncDelayed(t *testing.T) { busADone := false busBDone := false - busA.On("PingEvent", "handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("PingEvent", "handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(20 * time.Millisecond) busADone = true return nil, nil }, nil) - busB.On("PingEvent", "handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("PingEvent", "handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) busBDone = true return nil, nil }, nil) - busA.On("*", "delayed_forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("*", "delayed_forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) busB.Emit(event) return nil, nil }, nil) - event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 3})) + event := busA.EmitEventName("PingEvent", map[string]any{"value": 3}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -334,18 +334,18 @@ func TestForwardingSameEventDoesNotSetSelfParentID(t *testing.T) { defer origin.Destroy() defer target.Destroy() - origin.On("SelfParentForwardEvent", "origin_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + origin.OnEventName("SelfParentForwardEvent", "origin_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "origin-ok", nil }, nil) - target.On("SelfParentForwardEvent", "target_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + target.OnEventName("SelfParentForwardEvent", "target_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "target-ok", nil }, nil) - origin.On("*", "forward_to_target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + origin.OnEventName("*", "forward_to_target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { target.Emit(event) return nil, nil }, nil) - event := origin.Emit(abxbus.NewBaseEvent("SelfParentForwardEvent", nil)) + event := origin.EmitEventName("SelfParentForwardEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -386,7 +386,7 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { release := make(chan struct{}) var inheritedRef *abxbus.BaseEvent - busB.On("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { if e.EventTimeout != nil || e.EventHandlerConcurrency != "" || e.EventHandlerCompletion != "" { t.Fatalf("forwarded event should keep defaults unset in handler: %#v", e) } @@ -397,7 +397,7 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { appendEntry(mode + ":b1_end") return "b1", nil }, nil) - busB.On("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { if e.EventTimeout != nil || e.EventHandlerConcurrency != "" || e.EventHandlerCompletion != "" { t.Fatalf("forwarded event should keep defaults unset in handler: %#v", e) } @@ -407,8 +407,8 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { appendEntry(mode + ":b2_end") return "b2", nil }, nil) - busA.On("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - inherited := e.Emit(abxbus.NewBaseEvent("ForwardedDefaultsChildEvent", map[string]any{"mode": "inherited"})) + busA.OnEventName("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + inherited := e.EmitEventName("ForwardedDefaultsChildEvent", map[string]any{"mode": "inherited"}) inheritedRef = inherited busB.Emit(inherited) if _, err := inherited.Now(); err != nil { @@ -417,7 +417,7 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { return nil, nil }, nil) - top := busA.Emit(abxbus.NewBaseEvent("ForwardedDefaultsTriggerEvent", nil)) + top := busA.EmitEventName("ForwardedDefaultsTriggerEvent", nil) select { case <-h1Started: case <-time.After(2 * time.Second): @@ -477,7 +477,7 @@ func TestForwardedEventPreservesExplicitHandlerConcurrencyOverride(t *testing.T) h2Started := make(chan struct{}, 1) release := make(chan struct{}) - busB.On("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mode := e.Payload["mode"].(string) appendEntry(mode + ":b1_start") h1Started <- struct{}{} @@ -485,15 +485,15 @@ func TestForwardedEventPreservesExplicitHandlerConcurrencyOverride(t *testing.T) appendEntry(mode + ":b1_end") return "b1", nil }, nil) - busB.On("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mode := e.Payload["mode"].(string) appendEntry(mode + ":b2_start") h2Started <- struct{}{} appendEntry(mode + ":b2_end") return "b2", nil }, nil) - busA.On("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - override := e.Emit(abxbus.NewBaseEvent("ForwardedDefaultsChildEvent", map[string]any{"mode": "override"})) + busA.OnEventName("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + override := e.EmitEventName("ForwardedDefaultsChildEvent", map[string]any{"mode": "override"}) override.EventHandlerConcurrency = abxbus.EventHandlerConcurrencySerial busB.Emit(override) if _, err := override.Now(); err != nil { @@ -502,7 +502,7 @@ func TestForwardedEventPreservesExplicitHandlerConcurrencyOverride(t *testing.T) return nil, nil }, nil) - top := busA.Emit(abxbus.NewBaseEvent("ForwardedDefaultsTriggerEvent", nil)) + top := busA.EmitEventName("ForwardedDefaultsTriggerEvent", nil) select { case <-h1Started: case <-time.After(2 * time.Second): @@ -546,24 +546,24 @@ func TestForwardedFirstModeUsesProcessingBusHandlerConcurrencyDefaults(t *testin log = append(log, v) } - busA.On("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busB.Emit(event) return nil, nil }, nil) - busB.On("ForwardedFirstDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ForwardedFirstDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLog("slow_start") time.Sleep(20 * time.Millisecond) appendLog("slow_end") return "slow", nil }, nil) - busB.On("ForwardedFirstDefaultsEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ForwardedFirstDefaultsEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLog("fast_start") time.Sleep(time.Millisecond) appendLog("fast_end") return "fast", nil }, nil) - event := busA.Emit(abxbus.NewBaseEvent("ForwardedFirstDefaultsEvent", nil)) + event := busA.EmitEventName("ForwardedFirstDefaultsEvent", nil) if _, err := event.Now(&abxbus.EventWaitOptions{FirstResult: true}); err != nil { t.Fatal(err) } @@ -587,15 +587,15 @@ func TestProxyDispatchAutoLinksChildEventsLikeEmit(t *testing.T) { bus := abxbus.NewEventBus("ProxyDispatchAutoLinkBus", nil) defer bus.Destroy() - bus.On("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - event.Emit(abxbus.NewBaseEvent("ProxyDispatchChildEvent", nil)) + bus.OnEventName("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + event.EmitEventName("ProxyDispatchChildEvent", nil) return "root", nil }, nil) - bus.On("ProxyDispatchChildEvent", "child_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ProxyDispatchChildEvent", "child_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - root := bus.Emit(abxbus.NewBaseEvent("ProxyDispatchRootEvent", nil)) + root := bus.EmitEventName("ProxyDispatchRootEvent", nil) if _, err := root.Now(); err != nil { t.Fatal(err) } @@ -614,12 +614,12 @@ func TestProxyDispatchOfSameEventDoesNotSelfParentOrSelfLinkChild(t *testing.T) bus := abxbus.NewEventBus("ProxyDispatchSameEventBus", nil) defer bus.Destroy() - bus.On("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { event.Emit(event) return "root", nil }, nil) - root := bus.Emit(abxbus.NewBaseEvent("ProxyDispatchRootEvent", nil)) + root := bus.EmitEventName("ProxyDispatchRootEvent", nil) if _, err := root.Now(); err != nil { t.Fatal(err) } @@ -639,7 +639,7 @@ func TestEventsAreProcessedInFIFOOrder(t *testing.T) { processedOrders := []int{} handlerStartTimes := []time.Time{} - bus.On("OrderEvent", "order_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("OrderEvent", "order_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { handlerStartTimes = append(handlerStartTimes, time.Now()) order := event.Payload["order"].(int) if order%2 == 0 { @@ -652,7 +652,7 @@ func TestEventsAreProcessedInFIFOOrder(t *testing.T) { }, nil) for order := 0; order < 10; order++ { - bus.Emit(abxbus.NewBaseEvent("OrderEvent", map[string]any{"order": order})) + bus.EmitEventName("OrderEvent", map[string]any{"order": order}) } waitAllIdle(t, bus) @@ -672,27 +672,27 @@ func registerCycle(t *testing.T, peer1, peer2, peer3 *abxbus.EventBus) (*[]strin seen1 := []string{} seen2 := []string{} seen3 := []string{} - peer1.On("PingEvent", "seen_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer1.OnEventName("PingEvent", "seen_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen1 = append(seen1, event.EventID) return "p1", nil }, nil) - peer2.On("PingEvent", "seen_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer2.OnEventName("PingEvent", "seen_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen2 = append(seen2, event.EventID) return "p2", nil }, nil) - peer3.On("PingEvent", "seen_3", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer3.OnEventName("PingEvent", "seen_3", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen3 = append(seen3, event.EventID) return "p3", nil }, nil) - peer1.On("*", "forward_to_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer1.OnEventName("*", "forward_to_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { peer2.Emit(event) return nil, nil }, nil) - peer2.On("*", "forward_to_3", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer2.OnEventName("*", "forward_to_3", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { peer3.Emit(event) return nil, nil }, nil) - peer3.On("*", "forward_to_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer3.OnEventName("*", "forward_to_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { peer1.Emit(event) return nil, nil }, nil) diff --git a/abxbus-go/tests/eventbus_locking_test.go b/abxbus-go/tests/eventbus_locking_test.go index 5261bee2..05ae3f9c 100644 --- a/abxbus-go/tests/eventbus_locking_test.go +++ b/abxbus-go/tests/eventbus_locking_test.go @@ -38,12 +38,12 @@ func TestGlobalSerialAcrossBuses(t *testing.T) { } } - b1.On("Evt", "h1", h("b1"), nil) - b2.On("Evt", "h2", h("b2"), nil) + b1.OnEventName("Evt", "h1", h("b1"), nil) + b2.OnEventName("Evt", "h2", h("b2"), nil) for i := 1; i <= 3; i++ { - b1.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": i})) - b2.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": i})) + b1.EmitEventName("Evt", map[string]any{"n": i}) + b2.EmitEventName("Evt", map[string]any{"n": i}) } timeout := 2.0 @@ -96,22 +96,22 @@ func TestGlobalSerialAwaitedChildJumpsAheadOfQueuedEventsAcrossBuses(t *testing. order = append(order, value) } - busB.On("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") time.Sleep(5 * time.Millisecond) record("child_end") return "child", nil }, nil) - busB.On("QueuedEvent", "queued", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("QueuedEvent", "queued", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("queued_start") time.Sleep(time.Millisecond) record("queued_end") return "queued", nil }, nil) - busA.On("ParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("ParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - busB.Emit(abxbus.NewBaseEvent("QueuedEvent", nil)) - child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) + busB.EmitEventName("QueuedEvent", nil) + child := e.EmitEventName("ChildEvent", nil) busB.Emit(child) record("child_dispatched") if _, err := child.Now(); err != nil { @@ -122,7 +122,7 @@ func TestGlobalSerialAwaitedChildJumpsAheadOfQueuedEventsAcrossBuses(t *testing. return "parent", nil }, nil) - parent := busA.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + parent := busA.EmitEventName("ParentEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -181,12 +181,12 @@ func TestEventConcurrencyBusSerialSerializesPerBusButOverlapsAcrossBuses(t *test return label, nil } } - busA.On("Evt", "a", handler("a", startedA, releaseA), nil) - busB.On("Evt", "b", handler("b", startedB, releaseB), nil) + busA.OnEventName("Evt", "a", handler("a", startedA, releaseA), nil) + busB.OnEventName("Evt", "b", handler("b", startedB, releaseB), nil) - firstA := busA.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 1})) - secondA := busA.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 2})) - firstB := busB.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 1})) + firstA := busA.EmitEventName("Evt", map[string]any{"n": 1}) + secondA := busA.EmitEventName("Evt", map[string]any{"n": 2}) + firstB := busB.EmitEventName("Evt", map[string]any{"n": 1}) select { case <-startedA: @@ -236,7 +236,7 @@ func TestEventConcurrencyParallelAllowsSameBusEventsToOverlap(t *testing.T) { var mu sync.Mutex inFlight := 0 maxInFlight := 0 - bus.On("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -251,8 +251,8 @@ func TestEventConcurrencyParallelAllowsSameBusEventsToOverlap(t *testing.T) { return e.Payload["n"], nil }, nil) - first := bus.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 1})) - second := bus.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 2})) + first := bus.EmitEventName("Evt", map[string]any{"n": 1}) + second := bus.EmitEventName("Evt", map[string]any{"n": 2}) for i := 0; i < 2; i++ { select { case <-started: @@ -290,7 +290,7 @@ func TestEventConcurrencyOverrideParallelBeatsBusSerialDefault(t *testing.T) { var mu sync.Mutex inFlight := 0 maxInFlight := 0 - bus.On("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -349,7 +349,7 @@ func TestEventConcurrencyOverrideBusSerialBeatsBusParallelDefault(t *testing.T) var mu sync.Mutex inFlight := 0 maxInFlight := 0 - bus.On("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -418,7 +418,7 @@ func TestHandlerConcurrencyParallelStartsBoth(t *testing.T) { started := make(chan struct{}, 2) for i := 0; i < 2; i++ { - bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() count++ mu.Unlock() @@ -428,7 +428,7 @@ func TestHandlerConcurrencyParallelStartsBoth(t *testing.T) { }, nil) } - e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e := bus.EmitEventName("Evt", nil) deadline := time.After(2 * time.Second) for i := 0; i < 2; i++ { select { @@ -478,8 +478,8 @@ func TestEventHandlerConcurrencyPerEventOverrideControlsExecutionMode(t *testing mu.Unlock() return mode, nil } - bus.On("Evt", "first", handler, nil) - bus.On("Evt", "second", handler, nil) + bus.OnEventName("Evt", "first", handler, nil) + bus.OnEventName("Evt", "second", handler, nil) parallelEvent := abxbus.NewBaseEvent("Evt", map[string]any{"mode": "parallel"}) parallelEvent.EventHandlerConcurrency = abxbus.EventHandlerConcurrencyParallel diff --git a/abxbus-go/tests/eventbus_log_tree_test.go b/abxbus-go/tests/eventbus_log_tree_test.go index e892e6f4..1170dcd8 100644 --- a/abxbus-go/tests/eventbus_log_tree_test.go +++ b/abxbus-go/tests/eventbus_log_tree_test.go @@ -11,18 +11,18 @@ import ( func TestLogTreeShowsParentChildAndHandlerResults(t *testing.T) { bus := abxbus.NewEventBus("TreeBus", nil) - bus.On("RootEvent", "root", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) + bus.OnEventName("RootEvent", "root", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := e.EmitEventName("ChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } return "root-ok", nil }, nil) - bus.On("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child-ok", nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("RootEvent", nil)) + e := bus.EmitEventName("RootEvent", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -39,7 +39,7 @@ func TestLogTreeShowsParentChildAndHandlerResults(t *testing.T) { func TestLogTreeIncludesTimedOutResultErrors(t *testing.T) { short := 0.01 bus := abxbus.NewEventBus("TimeoutTreeBus", &abxbus.EventBusOptions{EventTimeout: &short}) - bus.On("SlowEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SlowEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(30 * time.Millisecond): return "too-late", nil @@ -47,7 +47,7 @@ func TestLogTreeIncludesTimedOutResultErrors(t *testing.T) { return nil, ctx.Err() } }, nil) - e := bus.Emit(abxbus.NewBaseEvent("SlowEvent", nil)) + e := bus.EmitEventName("SlowEvent", nil) if _, err := e.EventResult(); err == nil { t.Fatal("expected timeout error from event result") } diff --git a/abxbus-go/tests/eventbus_on_off_test.go b/abxbus-go/tests/eventbus_on_off_test.go index ed47f29b..24f72619 100644 --- a/abxbus-go/tests/eventbus_on_off_test.go +++ b/abxbus-go/tests/eventbus_on_off_test.go @@ -13,20 +13,20 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { var eventCalls atomic.Int32 var wildcardCalls atomic.Int32 - h1 := bus.On("Evt", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + h1 := bus.OnEventName("Evt", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { eventCalls.Add(1) return "h1", nil }, nil) - h2 := bus.On("Evt", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + h2 := bus.OnEventName("Evt", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { eventCalls.Add(1) return "h2", nil }, nil) - bus.On("*", "all", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("*", "all", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { wildcardCalls.Add(1) return "all", nil }, nil) - e1 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e1 := bus.EmitEventName("Evt", nil) if _, err := e1.Now(); err != nil { t.Fatal(err) } @@ -38,7 +38,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("Evt", h1) - e2 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e2 := bus.EmitEventName("Evt", nil) if _, err := e2.Now(); err != nil { t.Fatal(err) } @@ -50,7 +50,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("Evt", h2.ID) - e3 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e3 := bus.EmitEventName("Evt", nil) if _, err := e3.Now(); err != nil { t.Fatal(err) } @@ -62,7 +62,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("Evt", nil) - e4 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e4 := bus.EmitEventName("Evt", nil) if _, err := e4.Now(); err != nil { t.Fatal(err) } @@ -71,7 +71,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("*", nil) - e5 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e5 := bus.EmitEventName("Evt", nil) if _, err := e5.Now(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_performance_test.go b/abxbus-go/tests/eventbus_performance_test.go index d5778e2b..ee1954d6 100644 --- a/abxbus-go/tests/eventbus_performance_test.go +++ b/abxbus-go/tests/eventbus_performance_test.go @@ -44,7 +44,7 @@ func TestPerformance50kEvents(t *testing.T) { var processed int64 var checksum int64 var expectedChecksum int64 - bus.On("PerfSimpleEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PerfSimpleEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&processed, 1) value, _ := event.Payload["value"].(int) batchID, _ := event.Payload["batch_id"].(int) @@ -57,7 +57,7 @@ func TestPerformance50kEvents(t *testing.T) { for i := 0; i < totalEvents; i++ { payload := map[string]any{"value": i, "batch_id": i % 17} expectedChecksum += int64(i + i%17) - pending = append(pending, bus.Emit(abxbus.NewBaseEvent("PerfSimpleEvent", payload))) + pending = append(pending, bus.EmitEventName("PerfSimpleEvent", payload)) if len(pending) >= batchSize { waitForPerformanceBatch(t, pending) pending = pending[:0] @@ -96,13 +96,13 @@ func TestPerformanceEphemeralBuses(t *testing.T) { MaxHistorySize: &historySize, MaxHistoryDrop: true, }) - bus.On("PerfEphemeralEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PerfEphemeralEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&processed, 1) return nil, nil }, nil) pending := make([]*abxbus.BaseEvent, 0, eventsPerBus) for eventIndex := 0; eventIndex < eventsPerBus; eventIndex++ { - pending = append(pending, bus.Emit(abxbus.NewBaseEvent("PerfEphemeralEvent", nil))) + pending = append(pending, bus.EmitEventName("PerfEphemeralEvent", nil)) } waitForPerformanceBatch(t, pending) timeout := 2.0 @@ -134,14 +134,14 @@ func TestPerformanceSingleEventManyParallelHandlers(t *testing.T) { var handled int64 for index := 0; index < totalHandlers; index++ { handlerID := fmt.Sprintf("perf-fixed-handler-%05d", index) - bus.On("PerfFixedHandlersEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PerfFixedHandlersEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&handled, 1) return nil, nil }, &abxbus.EventHandler{ID: handlerID}) } started := time.Now() - event := bus.Emit(abxbus.NewBaseEvent("PerfFixedHandlersEvent", nil)) + event := bus.EmitEventName("PerfFixedHandlersEvent", nil) waitForPerformanceBatch(t, []*abxbus.BaseEvent{event}) timeout := 10.0 if !bus.WaitUntilIdle(&timeout) { @@ -168,11 +168,11 @@ func TestPerformanceOnOffChurn(t *testing.T) { started := time.Now() for index := 0; index < totalEvents; index++ { handlerID := fmt.Sprintf("perf-one-off-handler-%05d", index) - handler := bus.On("PerfOneOffEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.OnEventName("PerfOneOffEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&handled, 1) return nil, nil }, &abxbus.EventHandler{ID: handlerID}) - event := bus.Emit(abxbus.NewBaseEvent("PerfOneOffEvent", nil)) + event := bus.EmitEventName("PerfOneOffEvent", nil) waitForPerformanceBatch(t, []*abxbus.BaseEvent{event}) bus.Off("PerfOneOffEvent", handler) } @@ -207,13 +207,13 @@ func TestPerformanceWorstCaseForwardingQueueJumpTimeouts(t *testing.T) { var parents int64 var children int64 var timedOut int64 - parentBus.On("WCParent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parentBus.OnEventName("WCParent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&parents, 1) - child := childBus.Emit(abxbus.NewBaseEvent("WCChild", map[string]any{"parent": event.EventID, "iteration": event.Payload["iteration"]})) + child := childBus.EmitEventName("WCChild", map[string]any{"parent": event.EventID, "iteration": event.Payload["iteration"]}) _, _ = child.Now() return nil, nil }, nil) - childBus.On("WCChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + childBus.OnEventName("WCChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&children, 1) iteration, _ := event.Payload["iteration"].(int) if iteration%10 != 0 { @@ -231,7 +231,7 @@ func TestPerformanceWorstCaseForwardingQueueJumpTimeouts(t *testing.T) { pending := make([]*abxbus.BaseEvent, 0, 128) started := time.Now() for index := 0; index < totalEvents; index++ { - pending = append(pending, parentBus.Emit(abxbus.NewBaseEvent("WCParent", map[string]any{"iteration": index}))) + pending = append(pending, parentBus.EmitEventName("WCParent", map[string]any{"iteration": index})) if len(pending) >= cap(pending) { waitForPerformanceBatchAllowErrors(t, pending) pending = pending[:0] @@ -272,19 +272,19 @@ func TestPerformanceCleanupDestroyKeepsStateBounded(t *testing.T) { MaxHistorySize: &historySize, MaxHistoryDrop: true, }) - bus.On("CleanupEqEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CleanupEqEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) pending := make([]*abxbus.BaseEvent, 0, eventsPerBus) for eventIndex := 0; eventIndex < eventsPerBus; eventIndex++ { - pending = append(pending, bus.Emit(abxbus.NewBaseEvent("CleanupEqEvent", nil))) + pending = append(pending, bus.EmitEventName("CleanupEqEvent", nil)) } waitForPerformanceBatch(t, pending) bus.EventHistory.MaxHistorySize = &trimTarget bus.EventHistory.MaxHistoryDrop = true - trimEvent := bus.Emit(abxbus.NewBaseEvent("CleanupEqTrimEvent", nil)) + trimEvent := bus.EmitEventName("CleanupEqTrimEvent", nil) waitForPerformanceBatch(t, []*abxbus.BaseEvent{trimEvent}) timeout := 2.0 if !bus.WaitUntilIdle(&timeout) { @@ -346,7 +346,7 @@ func runFanoutBenchmark(t *testing.T, mode abxbus.EventHandlerConcurrencyMode) ( var handled int64 for index := 0; index < handlersPerEvent; index++ { handlerID := fmt.Sprintf("fanout-handler-%d", index) - bus.On("PerfFanoutEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("PerfFanoutEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(sleepDuration) atomic.AddInt64(&handled, 1) return nil, nil @@ -356,7 +356,7 @@ func runFanoutBenchmark(t *testing.T, mode abxbus.EventHandlerConcurrencyMode) ( pending := make([]*abxbus.BaseEvent, 0, 40) started := time.Now() for index := 0; index < totalEvents; index++ { - pending = append(pending, bus.Emit(abxbus.NewBaseEvent("PerfFanoutEvent", nil))) + pending = append(pending, bus.EmitEventName("PerfFanoutEvent", nil)) if len(pending) >= cap(pending) { waitForPerformanceBatch(t, pending) pending = pending[:0] diff --git a/abxbus-go/tests/eventbus_serialization_test.go b/abxbus-go/tests/eventbus_serialization_test.go index 36e01219..2bb4e0e2 100644 --- a/abxbus-go/tests/eventbus_serialization_test.go +++ b/abxbus-go/tests/eventbus_serialization_test.go @@ -39,8 +39,8 @@ func TestEventBusSerializationRoundtripPreservesConfigHandlersHistory(t *testing EventHandlerCompletion: abxbus.EventHandlerCompletionAll, EventHandlerSlowTimeout: &handlerSlowTimeout, }) - h := bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"k": "v"})) + h := bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) + e := bus.EmitEventName("Evt", map[string]any{"k": "v"}) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -113,8 +113,8 @@ func TestEventBusSerializationRoundtripPreservesConfigHandlersHistory(t *testing t.Fatalf("restored idle bus should start with clean runtime state") } - restored.On("Evt2", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok2", nil }, nil) - v, err := restored.Emit(abxbus.NewBaseEvent("Evt2", nil)).EventResult() + restored.OnEventName("Evt2", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok2", nil }, nil) + v, err := restored.EmitEventName("Evt2", nil).EventResult() if err != nil || v != "ok2" { t.Fatalf("restored bus should remain functional, result=%#v err=%v", v, err) } @@ -175,10 +175,10 @@ func TestEventBusFromJSONDefaultsMissingHandlerMaps(t *testing.T) { if err != nil { t.Fatal(err) } - restored.On("Evt", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + restored.OnEventName("Evt", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - result, err := restored.Emit(abxbus.NewBaseEvent("Evt", nil)).EventResult() + result, err := restored.EmitEventName("Evt", nil).EventResult() if err != nil { t.Fatal(err) } @@ -196,11 +196,11 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes }) originalOrder := []string{} - first := bus.On("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + first := bus.OnEventName("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { originalOrder = append(originalOrder, "first") return "first", nil }, nil) - second := bus.On("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + second := bus.OnEventName("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { originalOrder = append(originalOrder, "second") return "second", nil }, nil) @@ -219,7 +219,7 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes t.Fatalf("handlers_by_key order mismatch: got %v want %v", got, expectedIDs) } - if _, err := bus.Emit(abxbus.NewBaseEvent("HandlerOrderEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventName("HandlerOrderEvent", nil).Now(); err != nil { t.Fatal(err) } if len(originalOrder) != 2 || originalOrder[0] != "first" || originalOrder[1] != "second" { @@ -244,11 +244,11 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes } restoredOrder := []string{} - restored.On("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + restored.OnEventName("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { restoredOrder = append(restoredOrder, "first") return "first", nil }, payload.Handlers[first.ID]) - restored.On("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + restored.OnEventName("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { restoredOrder = append(restoredOrder, "second") return "second", nil }, payload.Handlers[second.ID]) @@ -265,7 +265,7 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes t.Fatalf("reattached handlers_by_key order mismatch: got %v want %v", got, expectedIDs) } - if _, err := restored.Emit(abxbus.NewBaseEvent("HandlerOrderEvent", nil)).Now(); err != nil { + if _, err := restored.EmitEventName("HandlerOrderEvent", nil).Now(); err != nil { t.Fatal(err) } if len(restoredOrder) != 2 || restoredOrder[0] != "first" || restoredOrder[1] != "second" { @@ -275,10 +275,10 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes func TestEventBusFromJSONRecreatesMissingHandlerEntriesFromEventResultMetadata(t *testing.T) { bus := abxbus.NewEventBus("MissingHandlerHydrationBus", nil) - bus.On("SerializableEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SerializableEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("SerializableEvent", nil)) + event := bus.EmitEventName("SerializableEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -331,11 +331,11 @@ func TestEventBusFromJSONRecreatesMissingHandlerEntriesFromEventResultMetadata(t func TestBaseEventFromJSONRoundtripsRuntimeJSONShape(t *testing.T) { bus := abxbus.NewEventBus("SerializableBaseEventBus", nil) defer bus.Destroy() - bus.On("SerializableBaseEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SerializableBaseEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("SerializableBaseEvent", nil)) + event := bus.EmitEventName("SerializableBaseEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -360,15 +360,15 @@ func TestEventBusSerializationPreservesPendingQueueIDs(t *testing.T) { bus := abxbus.NewEventBus("PendingSerBus", &abxbus.EventBusOptions{EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial}) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.On("BlockedEvt", "block", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("BlockedEvt", "block", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return "done", nil }, nil) - first := bus.Emit(abxbus.NewBaseEvent("BlockedEvt", nil)) + first := bus.EmitEventName("BlockedEvt", nil) <-started - second := bus.Emit(abxbus.NewBaseEvent("BlockedEvt", nil)) + second := bus.EmitEventName("BlockedEvt", nil) data, err := bus.ToJSON() if err != nil { diff --git a/abxbus-go/tests/eventbus_test.go b/abxbus-go/tests/eventbus_test.go index 4f23796c..9c094667 100644 --- a/abxbus-go/tests/eventbus_test.go +++ b/abxbus-go/tests/eventbus_test.go @@ -38,11 +38,11 @@ func TestEmitAndDispatchUseDefaultBehavior(t *testing.T) { } calls := []string{} - bus.On("CreateUserEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CreateUserEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "first") return "first", nil }, nil) - bus.On("CreateUserEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CreateUserEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "second") return map[string]any{"user_id": "abc"}, nil }, nil) @@ -96,12 +96,12 @@ func TestUnboundedHistoryDisablesHistoryRejection(t *testing.T) { func TestMaxHistoryDropFalseRejectsNewDispatchWhenHistoryIsFull(t *testing.T) { maxHistorySize := 2 bus := abxbus.NewEventBus("NoDropHistBus", &abxbus.EventBusOptions{MaxHistorySize: &maxHistorySize}) - bus.On("NoDropEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("NoDropEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) for i := 1; i <= 2; i++ { - event := bus.Emit(abxbus.NewBaseEvent("NoDropEvent", map[string]any{"seq": i})) + event := bus.EmitEventName("NoDropEvent", map[string]any{"seq": i}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -122,7 +122,7 @@ func TestMaxHistoryDropFalseRejectsNewDispatchWhenHistoryIsFull(t *testing.T) { t.Fatalf("history should remain capped after rejected emit, got %d", bus.EventHistory.Size()) } }() - bus.Emit(abxbus.NewBaseEvent("NoDropEvent", map[string]any{"seq": 3})) + bus.EmitEventName("NoDropEvent", map[string]any{"seq": 3}) } func TestZeroHistorySizeKeepsInflightAndDropsOnCompletion(t *testing.T) { @@ -130,7 +130,7 @@ func TestZeroHistorySizeKeepsInflightAndDropsOnCompletion(t *testing.T) { bus := abxbus.NewEventBus("ZeroHistoryBus", &abxbus.EventBusOptions{MaxHistorySize: &zeroHistorySize}) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.On("SlowEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SlowEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case started <- struct{}{}: default: @@ -139,14 +139,14 @@ func TestZeroHistorySizeKeepsInflightAndDropsOnCompletion(t *testing.T) { return "ok", nil }, nil) - first := bus.Emit(abxbus.NewBaseEvent("SlowEvent", nil)) + first := bus.EmitEventName("SlowEvent", nil) select { case <-started: case <-time.After(2 * time.Second): close(release) t.Fatal("timed out waiting for first handler to start") } - second := bus.Emit(abxbus.NewBaseEvent("SlowEvent", nil)) + second := bus.EmitEventName("SlowEvent", nil) if !bus.EventHistory.Has(first.EventID) || !bus.EventHistory.Has(second.EventID) { close(release) t.Fatalf("zero history should keep in-flight events, size=%d", bus.EventHistory.Size()) @@ -171,14 +171,14 @@ func TestZeroHistoryNoDropAllowsBurstQueueingAndDropsCompletedEvents(t *testing. zeroHistorySize := 0 bus := abxbus.NewEventBus("ZeroHistNoDropBus", &abxbus.EventBusOptions{MaxHistorySize: &zeroHistorySize, MaxHistoryDrop: false}) release := make(chan struct{}) - bus.On("BurstEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("BurstEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-release return "ok", nil }, nil) events := make([]*abxbus.BaseEvent, 0, 25) for i := 0; i < 25; i++ { - events = append(events, bus.Emit(abxbus.NewBaseEvent("BurstEvent", map[string]any{"seq": i}))) + events = append(events, bus.EmitEventName("BurstEvent", map[string]any{"seq": i})) } if bus.EventHistory.Size() == 0 { close(release) @@ -202,10 +202,10 @@ func TestZeroHistoryNoDropAllowsBurstQueueingAndDropsCompletedEvents(t *testing. func TestEventResultReturnsFirstCompletedResult(t *testing.T) { bus := abxbus.NewEventBus("SimpleBus", nil) - bus.On("ResultEvent", "on_create", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultEvent", "on_create", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"user_id": "abc"}, nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("ResultEvent", map[string]any{"email": "a@b.com"})) + e := bus.EmitEventName("ResultEvent", map[string]any{"email": "a@b.com"}) result, err := e.EventResult() if err != nil { t.Fatal(err) @@ -223,16 +223,16 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( bus := abxbus.NewEventBus("EventResultsOptionsBus", nil) defer bus.Destroy() - bus.On("ResultOptionsDefaultEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsDefaultEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.On("ResultOptionsDefaultEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsDefaultEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.On("ResultOptionsDefaultEvent", "forwarded", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsDefaultEvent", "forwarded", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return abxbus.NewBaseEvent("ForwardedResultEvent", nil), nil }, nil) - defaultEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsDefaultEvent", nil)) + defaultEvent := bus.EmitEventName("ResultOptionsDefaultEvent", nil) if _, err := defaultEvent.Now(); err != nil { t.Fatal(err) } @@ -244,13 +244,13 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( t.Fatalf("default result filtering mismatch: %#v", defaultValues) } - bus.On("ResultOptionsErrorEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsErrorEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.On("ResultOptionsErrorEvent", "boom", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsErrorEvent", "boom", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - errorEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsErrorEvent", nil)) + errorEvent := bus.EmitEventName("ResultOptionsErrorEvent", nil) if _, err := errorEvent.Now(); err != nil { t.Fatal(err) } @@ -265,10 +265,10 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( t.Fatalf("raise_if_any=false values mismatch: %#v", valuesWithoutErrors) } - bus.On("ResultOptionsEmptyEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsEmptyEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - emptyEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsEmptyEvent", nil)) + emptyEvent := bus.EmitEventName("ResultOptionsEmptyEvent", nil) if _, err := emptyEvent.Now(); err != nil { t.Fatal(err) } @@ -283,14 +283,14 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( t.Fatalf("raise_if_none=false should allow empty result list, got %#v", emptyValues) } - bus.On("ResultOptionsIncludeEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsIncludeEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "keep", nil }, nil) - bus.On("ResultOptionsIncludeEvent", "drop", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ResultOptionsIncludeEvent", "drop", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "drop", nil }, nil) seenHandlerNames := []string{} - includeEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsIncludeEvent", nil)) + includeEvent := bus.EmitEventName("ResultOptionsIncludeEvent", nil) if _, err := includeEvent.Now(); err != nil { t.Fatal(err) } @@ -417,13 +417,13 @@ func TestCompletionModeAllWaitsForAllHandlers(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) slowDone := false - bus.On("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) - bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) + bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) slowDone = true return "slow", nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e := bus.EmitEventName("Evt", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -438,12 +438,12 @@ func TestCompletionModeFirstSerialStopsAfterFirstNonNil(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) secondCalled := false - bus.On("Evt", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.On("Evt", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) + bus.OnEventName("Evt", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondCalled = true return "second", nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e := bus.EmitEventName("Evt", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -471,7 +471,7 @@ func TestCompletionModeFirstParallelReturnsFastAndCancelsSlow(t *testing.T) { }) slowStarted := make(chan struct{}, 1) slowExited := make(chan struct{}, 1) - bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { slowStarted <- struct{}{} select { case <-time.After(500 * time.Millisecond): @@ -482,7 +482,7 @@ func TestCompletionModeFirstParallelReturnsFastAndCancelsSlow(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.On("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) + bus.OnEventName("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) event := abxbus.NewBaseEvent("Evt", nil) event.EventHandlerCompletion = abxbus.EventHandlerCompletionFirst @@ -513,11 +513,11 @@ func TestCompletionModeFirstParallelReturnsFastAndCancelsSlow(t *testing.T) { func TestWaitUntilIdleTimeoutAndRecovery(t *testing.T) { bus := abxbus.NewEventBus("IdleTimeoutBus", nil) release := make(chan struct{}) - bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { <-release return nil, nil }, nil) - _ = bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + _ = bus.EmitEventName("Evt", nil) tShort := 0.01 if bus.WaitUntilIdle(&tShort) { @@ -537,20 +537,20 @@ func TestEventResetCreatesFreshPendingEventForCrossBusDispatch(t *testing.T) { seenA := []string{} seenB := []string{} - busA.On("ResetCoverageEvent", "record_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("ResetCoverageEvent", "record_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if label, ok := event.Payload["label"].(string); ok { seenA = append(seenA, label) } return "a:" + event.Payload["label"].(string), nil }, nil) - busB.On("ResetCoverageEvent", "record_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("ResetCoverageEvent", "record_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if label, ok := event.Payload["label"].(string); ok { seenB = append(seenB, label) } return "b:" + event.Payload["label"].(string), nil }, nil) - completed := busA.Emit(abxbus.NewBaseEvent("ResetCoverageEvent", map[string]any{"label": "hello"})) + completed := busA.EmitEventName("ResetCoverageEvent", map[string]any{"label": "hello"}) if _, err := completed.Now(); err != nil { t.Fatal(err) } @@ -605,12 +605,12 @@ func TestIsIdleAndQueueEmptyStates(t *testing.T) { started := make(chan struct{}, 1) release := make(chan struct{}) - bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return nil, nil }, nil) - _ = bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + _ = bus.EmitEventName("Evt", nil) select { case <-started: @@ -759,18 +759,18 @@ func assertRecordStatuses(t *testing.T, records []middlewareRecord, expected []s func TestEventBusMiddlewareReceivesPendingStartedCompletedLifecycleHooks(t *testing.T) { middleware := newRecordingMiddleware("single", nil) bus := abxbus.NewEventBus("MiddlewareBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - handler := bus.On("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.OnEventName("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) bus.Off("MiddlewareEvent", handler) - handler = bus.On("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler = bus.OnEventName("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, &abxbus.EventHandler{ ID: handler.ID, HandlerRegisteredAt: handler.HandlerRegisteredAt, }) - event := bus.Emit(abxbus.NewBaseEvent("MiddlewareEvent", nil)) + event := bus.EmitEventName("MiddlewareEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -809,11 +809,11 @@ func TestEventBusMiddlewareHooksExecuteInRegistrationOrder(t *testing.T) { bus := abxbus.NewEventBus("MiddlewareOrderBus", &abxbus.EventBusOptions{ Middlewares: []abxbus.EventBusMiddleware{first, second}, }) - bus.On("MiddlewareOrderEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MiddlewareOrderEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - if _, err := bus.Emit(abxbus.NewBaseEvent("MiddlewareOrderEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventName("MiddlewareOrderEvent", nil).Now(); err != nil { t.Fatal(err) } @@ -837,7 +837,7 @@ func TestEventBusMiddlewareNoHandlerEventLifecycle(t *testing.T) { middleware := newRecordingMiddleware("single", nil) bus := abxbus.NewEventBus("MiddlewareNoHandlerBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - event := bus.Emit(abxbus.NewBaseEvent("MiddlewareNoHandlerEvent", nil)) + event := bus.EmitEventName("MiddlewareNoHandlerEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -856,7 +856,7 @@ func TestEventBusMiddlewareEventLifecycleOrderingIsDeterministicPerEvent(t *test Middlewares: []abxbus.EventBusMiddleware{middleware}, MaxHistorySize: &historySize, }) - bus.On("MiddlewareDeterministicEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MiddlewareDeterministicEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(time.Millisecond) return "ok", nil }, nil) @@ -895,11 +895,11 @@ func TestEventBusMiddlewareEventLifecycleOrderingIsDeterministicPerEvent(t *test func TestEventBusMiddlewareHooksObserveHandlerErrorsWithoutErrorHookStatus(t *testing.T) { middleware := newRecordingMiddleware("errors", nil) bus := abxbus.NewEventBus("MiddlewareErrorBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - bus.On("MiddlewareErrorEvent", "failing", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MiddlewareErrorEvent", "failing", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - event := bus.Emit(abxbus.NewBaseEvent("MiddlewareErrorEvent", nil)) + event := bus.EmitEventName("MiddlewareErrorEvent", nil) _, err := event.EventResult() if err == nil || !strings.Contains(err.Error(), "boom") { t.Fatalf("expected handler error from event result, got %v", err) @@ -923,7 +923,7 @@ func TestEventBusMiddlewareHooksRemainMonotonicOnEventTimeout(t *testing.T) { Middlewares: []abxbus.EventBusMiddleware{middleware}, EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) - bus.On("MiddlewareTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MiddlewareTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "late", nil @@ -931,7 +931,7 @@ func TestEventBusMiddlewareHooksRemainMonotonicOnEventTimeout(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.On("MiddlewareTimeoutEvent", "pending", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MiddlewareTimeoutEvent", "pending", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "pending", nil }, nil) timeout := 0.02 @@ -964,7 +964,7 @@ func TestEventBusMiddlewareHardEventTimeoutFinalizesImmediatelyWithoutWaitingFor started := make(chan struct{}, 2) for _, handlerName := range []string{"slow_1", "slow_2"} { handlerName := handlerName - bus.On("MiddlewareHardTimeoutEvent", handlerName, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("MiddlewareHardTimeoutEvent", handlerName, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} time.Sleep(200 * time.Millisecond) return "late:" + handlerName, nil @@ -1019,7 +1019,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - serialBus.On("MiddlewareSchemaEvent", "bad_schema", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + serialBus.OnEventName("MiddlewareSchemaEvent", "bad_schema", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "not-a-number", nil }, nil) schemaEvent := abxbus.NewBaseEvent("MiddlewareSchemaEvent", nil) @@ -1038,7 +1038,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli } } - serialBus.On("MiddlewareSerialTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + serialBus.OnEventName("MiddlewareSerialTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow", nil @@ -1046,7 +1046,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli return nil, ctx.Err() } }, nil) - serialBus.On("MiddlewareSerialTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + serialBus.OnEventName("MiddlewareSerialTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow-2", nil @@ -1069,7 +1069,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli t.Fatalf("serial event timeout should abort or time out a running handler explicitly, got %#v", serialErrors) } - parallelBus.On("MiddlewareParallelTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parallelBus.OnEventName("MiddlewareParallelTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow", nil @@ -1077,7 +1077,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli return nil, ctx.Err() } }, nil) - parallelBus.On("MiddlewareParallelTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parallelBus.OnEventName("MiddlewareParallelTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow-2", nil @@ -1125,15 +1125,15 @@ func TestEventBusMiddlewareHooksArePerBusOnForwardedEvents(t *testing.T) { middlewareB := newRecordingMiddleware("b", nil) busA := abxbus.NewEventBus("MiddlewareForwardA", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middlewareA}}) busB := abxbus.NewEventBus("MiddlewareForwardB", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middlewareB}}) - handlerA := busA.On("MiddlewareForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerA := busA.OnEventName("MiddlewareForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busB.Emit(event) return "forwarded", nil }, nil) - handlerB := busB.On("MiddlewareForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerB := busB.OnEventName("MiddlewareForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "target", nil }, nil) - if _, err := busA.Emit(abxbus.NewBaseEvent("MiddlewareForwardEvent", nil)).Now(); err != nil { + if _, err := busA.EmitEventName("MiddlewareForwardEvent", nil).Now(); err != nil { t.Fatal(err) } @@ -1150,14 +1150,14 @@ func TestEventBusMiddlewareHooksArePerBusOnForwardedEvents(t *testing.T) { func TestEventBusMiddlewareHooksCoverStringAndWildcardPatterns(t *testing.T) { middleware := newRecordingMiddleware("patterns", nil) bus := abxbus.NewEventBus("MiddlewarePatternBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - stringHandler := bus.On("MiddlewarePatternEvent", "string", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + stringHandler := bus.OnEventName("MiddlewarePatternEvent", "string", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "string:" + event.EventType, nil }, nil) - wildcardHandler := bus.On("*", "wildcard", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + wildcardHandler := bus.OnEventName("*", "wildcard", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "wildcard:" + event.EventType, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("MiddlewarePatternEvent", nil)) + event := bus.EmitEventName("MiddlewarePatternEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1232,18 +1232,18 @@ func TestSameNameEventBusesKeepIndependentIDsHandlersAndHistory(t *testing.T) { t.Fatal("same-name buses should still have distinct ids") } - first.On("NameConflictEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + first.OnEventName("NameConflictEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - second.On("NameConflictEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + second.OnEventName("NameConflictEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "second", nil }, nil) - firstResult, err := first.Emit(abxbus.NewBaseEvent("NameConflictEvent", nil)).EventResult() + firstResult, err := first.EmitEventName("NameConflictEvent", nil).EventResult() if err != nil { t.Fatal(err) } - secondResult, err := second.Emit(abxbus.NewBaseEvent("NameConflictEvent", nil)).EventResult() + secondResult, err := second.EmitEventName("NameConflictEvent", nil).EventResult() if err != nil { t.Fatal(err) } @@ -1259,12 +1259,12 @@ func TestSameNameEventBusesKeepIndependentIDsHandlersAndHistory(t *testing.T) { func TestDestroyClearFalsePreservesHandlersAndHistoryResolvesWaitersAndIsTerminal(t *testing.T) { bus := abxbus.NewEventBus("DestroyClearFalseTerminalBus", nil) var calls atomic.Int32 - bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls.Add(1) return "ok", nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e := bus.EmitEventName("Evt", nil) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -1283,7 +1283,7 @@ func TestDestroyClearFalsePreservesHandlersAndHistoryResolvesWaitersAndIsTermina bus.DestroyWithOptions(&abxbus.EventBusDestroyOptions{Clear: false}) close(destroyed) }() - match, err := bus.Find("NeverHappens", nil, &abxbus.FindOptions{Past: false, Future: true}) + match, err := bus.FindEventName("NeverHappens", nil, &abxbus.FindOptions{Past: false, Future: true}) if err != nil { t.Fatal(err) } @@ -1330,13 +1330,13 @@ func TestDestroyClearFalsePreservesHandlersAndHistoryResolvesWaitersAndIsTermina }() fn() } - assertDestroyedPanic("Emit", func() { bus.Emit(abxbus.NewBaseEvent("Evt", nil)) }) + assertDestroyedPanic("Emit", func() { bus.EmitEventName("Evt", nil) }) assertDestroyedPanic("On", func() { - bus.On("Evt", "again", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "again", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) }) - if _, err := bus.Find("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { + if _, err := bus.FindEventName("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { t.Fatalf("Find should reject with ErrEventBusDestroyed, got %v", err) } } @@ -1348,7 +1348,7 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { lateEmitRejected := make(chan bool, 1) var startOnce sync.Once - bus.On("SlowEvt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("SlowEvt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { startOnce.Do(func() { close(started) }) <-release rejected := false @@ -1360,13 +1360,13 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { } } }() - bus.Emit(abxbus.NewBaseEvent("LateEvt", nil)) + bus.EmitEventName("LateEvt", nil) }() lateEmitRejected <- rejected return "slow", nil }, nil) - bus.Emit(abxbus.NewBaseEvent("SlowEvt", nil)) + bus.EmitEventName("SlowEvt", nil) select { case <-started: case <-time.After(2 * time.Second): @@ -1392,7 +1392,7 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { t.Fatalf("expected destroyed error panic, got %#v", recovered) } }() - bus.Emit(abxbus.NewBaseEvent("OutsideEvt", nil)) + bus.EmitEventName("OutsideEvt", nil) }() close(release) @@ -1409,10 +1409,10 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { func TestDestroyDefaultClearIsTerminalAndFreesBusState(t *testing.T) { bus := abxbus.NewEventBus("TerminalDestroyBus", nil) - bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + event := bus.EmitEventName("Evt", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1479,15 +1479,15 @@ func TestDestroyDefaultClearIsTerminalAndFreesBusState(t *testing.T) { }() fn() } - assertDestroyedPanic("Emit", func() { bus.Emit(abxbus.NewBaseEvent("Evt", nil)) }) + assertDestroyedPanic("Emit", func() { bus.EmitEventName("Evt", nil) }) assertDestroyedPanic("On", func() { - bus.On("Evt", "new", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) + bus.OnEventName("Evt", "new", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) }) - if _, err := bus.Find("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { + if _, err := bus.FindEventName("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { t.Fatalf("Find should reject with ErrEventBusDestroyed, got %v", err) } - if _, err := bus.Filter("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { + if _, err := bus.FilterEventName("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { t.Fatalf("Filter should reject with ErrEventBusDestroyed, got %v", err) } } @@ -1502,13 +1502,13 @@ func TestDestroyingOneBusDoesNotBreakSharedHandlersOrForwardTargets(t *testing.T seen.Add(1) return "shared", nil } - source.On("SharedDestroyEvent", "shared_source", shared, nil) - source.On("*", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + source.OnEventName("SharedDestroyEvent", "shared_source", shared, nil) + source.OnEventName("*", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return target.Emit(event), nil }, nil) - target.On("SharedDestroyEvent", "shared_target", shared, nil) + target.OnEventName("SharedDestroyEvent", "shared_target", shared, nil) - forwarded := source.Emit(abxbus.NewBaseEvent("SharedDestroyEvent", nil)) + forwarded := source.EmitEventName("SharedDestroyEvent", nil) if _, err := forwarded.Now(); err != nil { t.Fatal(err) } @@ -1518,7 +1518,7 @@ func TestDestroyingOneBusDoesNotBreakSharedHandlersOrForwardTargets(t *testing.T source.Destroy() - direct := target.Emit(abxbus.NewBaseEvent("SharedDestroyEvent", nil)) + direct := target.EmitEventName("SharedDestroyEvent", nil) completedDirect, err := direct.Now() if err != nil { t.Fatalf("target should still process after source destroy: %v", err) @@ -1631,11 +1631,11 @@ func TestOtelTracingMiddlewareCreatesEventAndHandlerSpans(t *testing.T) { }, }) bus := abxbus.NewEventBus("OtelBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - bus.On("OtelEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("OtelEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("OtelEvent", map[string]any{"session_id": "event-session-456", "value": "x"})) + event := bus.EmitEventName("OtelEvent", map[string]any{"session_id": "event-session-456", "value": "x"}) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1683,7 +1683,7 @@ func TestOtelTracingMiddlewareNamesEventAndHandlerSpansForDisplay(t *testing.T) }) bus := abxbus.NewEventBus("StagehandExtensionBackground", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) t.Cleanup(bus.Destroy) - bus.On("CDPConnect", "DebuggerClient.on_CDPConnect", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("CDPConnect", "DebuggerClient.on_CDPConnect", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "connected", nil }, nil) @@ -1707,18 +1707,18 @@ func TestOtelTracingMiddlewareParentsChildEventToEmittingHandlerSpan(t *testing. Tracer: provider.Tracer("abxbus-test"), }) bus := abxbus.NewEventBus("OtelParentBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - bus.On("ParentOtelEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := event.Emit(abxbus.NewBaseEvent("ChildOtelEvent", nil)) + bus.OnEventName("ParentOtelEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := event.EmitEventName("ChildOtelEvent", nil) if _, err := child.Now(); err != nil { return nil, err } return "parent", nil }, nil) - bus.On("ChildOtelEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ChildOtelEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - parent := bus.Emit(abxbus.NewBaseEvent("ParentOtelEvent", nil)) + parent := bus.EmitEventName("ParentOtelEvent", nil) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1760,7 +1760,7 @@ func TestOtelTracingMiddlewareWaitsUntilTopLevelEventCompletionBeforeEndingSpans started := make(chan struct{}) release := make(chan struct{}) - bus.On("OtelRootStartEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("OtelRootStartEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { close(started) select { case <-release: @@ -1811,11 +1811,11 @@ func TestOtelTracingMiddlewareRecordsHandlerErrors(t *testing.T) { }) bus := abxbus.NewEventBus("OtelErrorBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) handlerErr := errors.New("handler failed") - bus.On("OtelErrorEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("OtelErrorEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, handlerErr }, nil) - event := bus.Emit(abxbus.NewBaseEvent("OtelErrorEvent", nil)) + event := bus.EmitEventName("OtelErrorEvent", nil) if _, err := event.Wait(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_timeout_test.go b/abxbus-go/tests/eventbus_timeout_test.go index 1463a848..3dae0bd6 100644 --- a/abxbus-go/tests/eventbus_timeout_test.go +++ b/abxbus-go/tests/eventbus_timeout_test.go @@ -13,7 +13,7 @@ func TestTimeoutPrecedenceEventOverBus(t *testing.T) { busTimeout := 5.0 eventTimeout := 0.01 bus := abxbus.NewEventBus("TimeoutBus", &abxbus.EventBusOptions{EventTimeout: &busTimeout}) - bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, nil) @@ -37,7 +37,7 @@ func TestTimeoutPrecedenceEventOverBus(t *testing.T) { func TestZeroTimeoutAllowsSlowHandler(t *testing.T) { busTimeout := 0.01 bus := abxbus.NewEventBus("NoTimeoutBus", &abxbus.EventBusOptions{EventTimeout: &busTimeout}) - bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(20 * time.Millisecond) return "ok", nil }, nil) @@ -61,11 +61,11 @@ func TestProcessingTimeTimeoutDefaultsResolveAtExecutionTime(t *testing.T) { }) t.Cleanup(bus.Destroy) - bus.On("TimeoutEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("TimeoutEvent", nil)) + event := bus.EmitEventName("TimeoutEvent", nil) if event.EventTimeout != nil { t.Fatalf("expected nil event_timeout, got %#v", event.EventTimeout) } @@ -106,7 +106,7 @@ func TestEventTimeoutNilUsesBusDefaultTimeoutAtExecution(t *testing.T) { bus := abxbus.NewEventBus("TimeoutNilUsesBusDefault", &abxbus.EventBusOptions{EventTimeout: &busTimeout}) t.Cleanup(bus.Destroy) - bus.On("TimeoutDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(20 * time.Millisecond): return "slow", nil @@ -115,7 +115,7 @@ func TestEventTimeoutNilUsesBusDefaultTimeoutAtExecution(t *testing.T) { } }, nil) - event := bus.Emit(abxbus.NewBaseEvent("TimeoutDefaultsEvent", nil)) + event := bus.EmitEventName("TimeoutDefaultsEvent", nil) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -139,7 +139,7 @@ func TestHandlerTimeoutResolutionMatchesPrecedence(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionAll, EventHandlerDetectFilePaths: &detectPaths, }) - bus.On("TimeoutDefaultsEvent", "default_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutDefaultsEvent", "default_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { sleepFor := 80 * time.Millisecond if e.Payload["scenario"] == "event-cap" { sleepFor = 150 * time.Millisecond @@ -151,7 +151,7 @@ func TestHandlerTimeoutResolutionMatchesPrecedence(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.On("TimeoutDefaultsEvent", "overridden_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutDefaultsEvent", "overridden_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { sleepFor := 80 * time.Millisecond if e.Payload["scenario"] == "event-cap" { sleepFor = 150 * time.Millisecond @@ -215,13 +215,13 @@ func TestHandlerTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { lateAttempt := make(chan struct{}, 1) lateHandlerRan := false - bus.On("TimeoutIgnoresLateHandlerEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutIgnoresLateHandlerEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(40 * time.Millisecond) lateAttempt <- struct{}{} - event.Emit(abxbus.NewBaseEvent("LateAfterTimeoutEvent", nil)) + event.EmitEventName("LateAfterTimeoutEvent", nil) return "late success", nil }, &abxbus.EventHandler{HandlerTimeout: &handlerTimeout}) - bus.On("LateAfterTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("LateAfterTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { lateHandlerRan = true return "late child", nil }, nil) @@ -249,7 +249,7 @@ func TestHandlerTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { if slowResult.Result != nil { t.Fatalf("slow handler late result should be ignored, got %#v", slowResult.Result) } - found, err := bus.Find("LateAfterTimeoutEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + found, err := bus.FindEventName("LateAfterTimeoutEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -269,13 +269,13 @@ func TestEventTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { lateAttempt := make(chan struct{}, 1) lateHandlerRan := false - bus.On("TimeoutIgnoresLateEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutIgnoresLateEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(40 * time.Millisecond) lateAttempt <- struct{}{} - event.Emit(abxbus.NewBaseEvent("LateAfterEventTimeoutEvent", nil)) + event.EmitEventName("LateAfterEventTimeoutEvent", nil) return "late success", nil }, nil) - bus.On("LateAfterEventTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("LateAfterEventTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { lateHandlerRan = true return "late child", nil }, nil) @@ -302,7 +302,7 @@ func TestEventTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { if slowResult.Result != nil { t.Fatalf("slow handler late result should be ignored, got %#v", slowResult.Result) } - found, err := bus.Find("LateAfterEventTimeoutEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) + found, err := bus.FindEventName("LateAfterEventTimeoutEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { t.Fatal(err) } @@ -317,7 +317,7 @@ func TestEventTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { func TestEventHandlerDetectFilePathsToggle(t *testing.T) { detectPaths := false bus := abxbus.NewEventBus("NoDetectPathsBus", &abxbus.EventBusOptions{EventHandlerDetectFilePaths: &detectPaths}) - entry := bus.On("TimeoutDefaultsEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + entry := bus.OnEventName("TimeoutDefaultsEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) if entry.HandlerFilePath != nil { @@ -346,7 +346,7 @@ func TestHandlerSlowWarningUsesEventHandlerSlowTimeout(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) mu.Lock() messages = append(messages, "slow warning child handler finishing") @@ -395,7 +395,7 @@ func TestEventSlowWarningUsesEventSlowTimeout(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) mu.Lock() messages = append(messages, "slow warning child handler finishing") @@ -441,7 +441,7 @@ func TestSlowHandlerAndSlowEventWarningsCanBothFire(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "ok", nil }, nil) @@ -485,7 +485,7 @@ func TestZeroSlowWarningThresholdsDisableEventAndHandlerSlowWarnings(t *testing. } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) mu.Lock() messages = append(messages, "slow warning child handler finishing") @@ -493,7 +493,7 @@ func TestZeroSlowWarningThresholdsDisableEventAndHandlerSlowWarnings(t *testing. return "ok", nil }, nil) - if _, err := bus.Emit(abxbus.NewBaseEvent("TimeoutDefaultsEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventName("TimeoutDefaultsEvent", nil).Now(); err != nil { t.Fatal(err) } mu.Lock() @@ -515,10 +515,10 @@ func TestForwardedEventTimeoutAbortsTargetBusHandler(t *testing.T) { t.Cleanup(busA.Destroy) t.Cleanup(busB.Destroy) - busA.On("TimeoutForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("TimeoutForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return busB.Emit(event), nil }, nil) - busB.On("TimeoutForwardEvent", "slow_target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("TimeoutForwardEvent", "slow_target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(50 * time.Millisecond): return "slow", nil @@ -563,7 +563,7 @@ func TestQueueJumpAwaitedChildTimeoutAbortsAcrossBuses(t *testing.T) { t.Cleanup(busB.Destroy) var childRef *abxbus.BaseEvent - busB.On("TimeoutChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("TimeoutChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(50 * time.Millisecond): return "slow", nil @@ -571,9 +571,9 @@ func TestQueueJumpAwaitedChildTimeoutAbortsAcrossBuses(t *testing.T) { return nil, ctx.Err() } }, nil) - busA.On("TimeoutParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("TimeoutParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childTimeout := 0.01 - child := event.Emit(abxbus.NewBaseEvent("TimeoutChildEvent", nil)) + child := event.EmitEventName("TimeoutChildEvent", nil) child.EventTimeout = &childTimeout busB.Emit(child) childRef = child @@ -621,7 +621,7 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { busBTailRuns := 0 var childRef *abxbus.BaseEvent - busA.On("TimeoutRecoveryParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("TimeoutRecoveryParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childTimeout := 0.01 childEvent := abxbus.NewBaseEvent("TimeoutRecoveryChildEvent", nil) childEvent.EventTimeout = &childTimeout @@ -632,14 +632,14 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { } return "parent_done", nil }, nil) - busA.On("TimeoutRecoveryTailEvent", "tail_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("TimeoutRecoveryTailEvent", "tail_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busATailRuns++ return "tail_a", nil }, nil) - busA.On("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return busB.Emit(event), nil }, nil) - busB.On("TimeoutRecoveryChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("TimeoutRecoveryChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(50 * time.Millisecond): return "child_done", nil @@ -647,7 +647,7 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { return nil, ctx.Err() } }, nil) - busB.On("TimeoutRecoveryTailEvent", "tail_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.OnEventName("TimeoutRecoveryTailEvent", "tail_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busBTailRuns++ return "tail_b", nil }, nil) @@ -680,7 +680,7 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { t.Fatalf("expected child timeout/abort result, got %#v", childRef.EventResults) } - tail := busA.Emit(abxbus.NewBaseEvent("TimeoutRecoveryTailEvent", nil)) + tail := busA.EmitEventName("TimeoutRecoveryTailEvent", nil) if _, err := tail.Now(); err != nil { t.Fatal(err) } @@ -704,17 +704,17 @@ func TestParentTimeoutDoesNotCancelUnawaitedChildHandlerResultsUnderSerialHandle t.Cleanup(bus.Destroy) childRuns := 0 - bus.On("TimeoutCancelChildEvent", "child_first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCancelChildEvent", "child_first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childRuns++ time.Sleep(30 * time.Millisecond) return "first", nil }, nil) - bus.On("TimeoutCancelChildEvent", "child_second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCancelChildEvent", "child_second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childRuns++ time.Sleep(10 * time.Millisecond) return "second", nil }, nil) - bus.On("TimeoutCancelParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCancelParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childTimeout := 0.2 child := abxbus.NewBaseEvent("TimeoutCancelChildEvent", nil) child.EventTimeout = &childTimeout @@ -771,21 +771,21 @@ func TestMultiLevelTimeoutCascadeWithMixedCancellations(t *testing.T) { immediateGrandchildRuns := 0 queuedGrandchildRuns := 0 - bus.On("TimeoutCascadeQueuedChild", "queued_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeQueuedChild", "queued_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedChildRuns++ time.Sleep(5 * time.Millisecond) return "queued_fast", nil }, nil) - bus.On("TimeoutCascadeQueuedChild", "queued_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeQueuedChild", "queued_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedChildRuns++ time.Sleep(50 * time.Millisecond) return "queued_slow", nil }, nil) - bus.On("TimeoutCascadeAwaitedChild", "awaited_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeAwaitedChild", "awaited_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(5 * time.Millisecond) return "awaited_fast", nil }, nil) - bus.On("TimeoutCascadeAwaitedChild", "awaited_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeAwaitedChild", "awaited_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedTimeout := 0.2 queuedGrandchild = abxbus.NewBaseEvent("TimeoutCascadeQueuedGrandchild", nil) queuedGrandchild.EventTimeout = &queuedTimeout @@ -805,7 +805,7 @@ func TestMultiLevelTimeoutCascadeWithMixedCancellations(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.On("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { immediateGrandchildRuns++ select { case <-time.After(50 * time.Millisecond): @@ -814,22 +814,22 @@ func TestMultiLevelTimeoutCascadeWithMixedCancellations(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.On("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { immediateGrandchildRuns++ time.Sleep(10 * time.Millisecond) return "immediate_grandchild_fast", nil }, nil) - bus.On("TimeoutCascadeQueuedGrandchild", "queued_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeQueuedGrandchild", "queued_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedGrandchildRuns++ time.Sleep(50 * time.Millisecond) return "queued_grandchild_slow", nil }, nil) - bus.On("TimeoutCascadeQueuedGrandchild", "queued_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeQueuedGrandchild", "queued_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedGrandchildRuns++ time.Sleep(10 * time.Millisecond) return "queued_grandchild_fast", nil }, nil) - bus.On("TimeoutCascadeTop", "top", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutCascadeTop", "top", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedTimeout := 0.2 queuedChild = abxbus.NewBaseEvent("TimeoutCascadeQueuedChild", nil) queuedChild.EventTimeout = &queuedTimeout @@ -908,11 +908,11 @@ func TestUnawaitedDescendantPreservesLineageAndIsNotCancelledByAncestorTimeout(t var innerRef *abxbus.BaseEvent var deepRef *abxbus.BaseEvent - bus.On("ErrorChainDeep", "deep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ErrorChainDeep", "deep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(200 * time.Millisecond) return "deep_done", nil }, nil) - bus.On("ErrorChainInner", "inner", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ErrorChainInner", "inner", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { deepTimeout := 0.5 deepRef = abxbus.NewBaseEvent("ErrorChainDeep", nil) deepRef.EventTimeout = &deepTimeout @@ -924,7 +924,7 @@ func TestUnawaitedDescendantPreservesLineageAndIsNotCancelledByAncestorTimeout(t return nil, ctx.Err() } }, nil) - bus.On("ErrorChainOuter", "outer", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("ErrorChainOuter", "outer", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { innerTimeout := 0.04 innerRef = abxbus.NewBaseEvent("ErrorChainInner", nil) innerRef.EventTimeout = &innerTimeout @@ -989,12 +989,12 @@ func TestParentTimeoutDoesNotCancelUnawaitedChildrenThatHaveNoTimeoutOfTheirOwn( var childRef *abxbus.BaseEvent childHandlerRan := false - bus.On("TimeoutBoundaryChild", "child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutBoundaryChild", "child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childHandlerRan = true time.Sleep(80 * time.Millisecond) return "child_done", nil }, nil) - bus.On("TimeoutBoundaryParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("TimeoutBoundaryParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childRef = abxbus.NewBaseEvent("TimeoutBoundaryChild", nil) childRef.EventTimeout = nil childRef = event.Emit(childRef) @@ -1103,12 +1103,12 @@ func TestSlowEventAndHandlerWarnings(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = original }() - bus.On("Evt", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "ok", nil }, nil) - e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e := bus.EmitEventName("Evt", nil) _, err := e.Now() if err != nil { t.Fatal(err) @@ -1145,7 +1145,7 @@ func TestEventTimeoutMarksAbortedAndCancelledHandlers(t *testing.T) { EventHandlerSlowTimeout: &no_timeout, EventSlowTimeout: &no_timeout, }) - bus.On("Evt", "slow_first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow_first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(250 * time.Millisecond): return "late", nil @@ -1153,7 +1153,7 @@ func TestEventTimeoutMarksAbortedAndCancelledHandlers(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.On("Evt", "pending_second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "pending_second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "never", nil }, nil) @@ -1193,7 +1193,7 @@ func TestHandlerTimeoutUsesTimedOutErrorMessage(t *testing.T) { bus_timeout := 5.0 bus := abxbus.NewEventBus("HandlerTimeoutMessageBus", &abxbus.EventBusOptions{EventTimeout: &bus_timeout}) overrides := &abxbus.EventHandler{HandlerTimeout: &handler_timeout} - bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(200 * time.Millisecond): return "late", nil @@ -1201,7 +1201,7 @@ func TestHandlerTimeoutUsesTimedOutErrorMessage(t *testing.T) { return nil, ctx.Err() } }, overrides) - e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e := bus.EmitEventName("Evt", nil) _, err := e.EventResult() if err == nil { t.Fatal("expected timeout error") diff --git a/abxbus-go/tests/lock_manager_test.go b/abxbus-go/tests/lock_manager_test.go index 25fd6079..8862d2ff 100644 --- a/abxbus-go/tests/lock_manager_test.go +++ b/abxbus-go/tests/lock_manager_test.go @@ -19,7 +19,7 @@ func lockManagerUpdateMax(maxActive *atomic.Int32, value int32) { } func registerActiveLockManagerHandler(bus *abxbus.EventBus, eventType string, handlerName string, active *atomic.Int32, maxActive *atomic.Int32) { - bus.On(eventType, handlerName, func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName(eventType, handlerName, func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { nowActive := active.Add(1) lockManagerUpdateMax(maxActive, nowActive) time.Sleep(20 * time.Millisecond) @@ -120,7 +120,7 @@ func TestWaitUntilIdleBehavesCorrectly(t *testing.T) { bus := abxbus.NewEventBus("IdleBus", nil) defer bus.Destroy() var calls atomic.Int32 - bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls.Add(1) return "ok", nil }, nil) @@ -130,7 +130,7 @@ func TestWaitUntilIdleBehavesCorrectly(t *testing.T) { t.Fatal("bus should be idle before any events") } - e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) + e := bus.EmitEventName("Evt", nil) if !bus.WaitUntilIdle(&short) { t.Fatal("bus should become idle after event completion") } @@ -163,8 +163,8 @@ func TestLockManagerGetLockForEventModes(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) registerActiveLockManagerHandler(busSerial, "LockModesEvent", "handler", &active, &maxActive) - busSerial.Emit(abxbus.NewBaseEvent("LockModesEvent", nil)) - busSerial.Emit(abxbus.NewBaseEvent("LockModesEvent", nil)) + busSerial.EmitEventName("LockModesEvent", nil) + busSerial.EmitEventName("LockModesEvent", nil) if !busSerial.WaitUntilIdle(&timeout) { t.Fatal("bus-serial bus did not become idle") } @@ -235,7 +235,7 @@ func TestLockManagerGetLockForEventHandlerModes(t *testing.T) { }) registerActiveLockManagerHandler(serialBus, "LockHandlerModesEvent", "handler_a", &active, &maxActive) registerActiveLockManagerHandler(serialBus, "LockHandlerModesEvent", "handler_b", &active, &maxActive) - serialBus.Emit(abxbus.NewBaseEvent("LockHandlerModesEvent", nil)) + serialBus.EmitEventName("LockHandlerModesEvent", nil) if !serialBus.WaitUntilIdle(&timeout) { t.Fatal("serial handler bus did not become idle") } @@ -298,8 +298,8 @@ func TestRunWithEventLockAndHandlerLockRespectParallelBypass(t *testing.T) { }) registerActiveLockManagerHandler(serialBus, "SerialAcquireEvent", "handler_a", &active, &maxActive) registerActiveLockManagerHandler(serialBus, "SerialAcquireEvent", "handler_b", &active, &maxActive) - serialBus.Emit(abxbus.NewBaseEvent("SerialAcquireEvent", nil)) - serialBus.Emit(abxbus.NewBaseEvent("SerialAcquireEvent", nil)) + serialBus.EmitEventName("SerialAcquireEvent", nil) + serialBus.EmitEventName("SerialAcquireEvent", nil) if !serialBus.WaitUntilIdle(&timeout) { t.Fatal("serial acquire bus did not become idle") } diff --git a/abxbus-go/tests/roundtrip_cli/main.go b/abxbus-go/tests/roundtrip_cli/main.go index 854477de..a3e6b6e6 100644 --- a/abxbus-go/tests/roundtrip_cli/main.go +++ b/abxbus-go/tests/roundtrip_cli/main.go @@ -104,7 +104,7 @@ func runJSONLListener(configPath string) { received := make(chan struct{}) receivedOnce := sync.Once{} - bridge.On("*", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bridge.OnEventName("*", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { data, err := json.Marshal(event) if err != nil { return nil, err diff --git a/abxbus-go/typed.go b/abxbus-go/typed.go index 955d5539..e4dd9495 100644 --- a/abxbus-go/typed.go +++ b/abxbus-go/typed.go @@ -1,14 +1,11 @@ package abxbus import ( - "context" "encoding/json" "fmt" "reflect" "regexp" "strings" - - "github.com/ArchiveBox/abxbus/abxbus-go/v2/jsonschema" ) func Event[T any](payload T) (*BaseEvent, error) { @@ -166,7 +163,7 @@ func normalizeReflectValue(value reflect.Value) any { return value.Interface() } -func NewTypedEvent[T any](eventType string, payload T) (*BaseEvent, error) { +func newEventFromPayload[T any](eventType string, payload T) (*BaseEvent, error) { normalized := map[string]any{} data, err := json.Marshal(payload) if err != nil { @@ -180,155 +177,35 @@ func NewTypedEvent[T any](eventType string, payload T) (*BaseEvent, error) { return NewBaseEvent(eventType, normalized), nil } -func NewTypedEventWithResult[TPayload any, TResult any](eventType string, payload TPayload) (*BaseEvent, error) { - event, err := NewTypedEvent(eventType, payload) - if err != nil { - return nil, err +type EventOption func(*BaseEvent) + +func ResultType[T any]() EventOption { + return func(event *BaseEvent) { + event.EventResultType = JSONSchemaFor[T]() } - event.EventResultType = JSONSchemaFor[TResult]() - return event, nil } -func MustNewTypedEvent[T any](eventType string, payload T) *BaseEvent { - event, err := NewTypedEvent(eventType, payload) +func NewEvent[T any](eventType string, payload T, options ...EventOption) (*BaseEvent, error) { + event, err := newEventFromPayload(eventType, payload) if err != nil { - panic(err) + return nil, err } - return event + for _, option := range options { + if option != nil { + option(event) + } + } + return event, nil } -func MustNewTypedEventWithResult[TPayload any, TResult any](eventType string, payload TPayload) *BaseEvent { - event, err := NewTypedEventWithResult[TPayload, TResult](eventType, payload) +func MustNewEvent[T any](eventType string, payload T, options ...EventOption) *BaseEvent { + event, err := NewEvent(eventType, payload, options...) if err != nil { panic(err) } return event } -type TypedEventHandler[TPayload any, TResult any] interface { - ~func(TPayload) (TResult, error) | - ~func(TPayload, context.Context) (TResult, error) | - ~func(TPayload) TResult | - ~func(TPayload, context.Context) TResult | - ~func(TPayload) error | - ~func(TPayload, context.Context) error | - ~func(TPayload) | - ~func(TPayload, context.Context) -} - -func OnTyped[TPayload any, TResult any, THandler TypedEventHandler[TPayload, TResult]]( - bus *EventBus, - eventPattern string, - handlerName string, - handler THandler, - options *EventHandler, -) *EventHandler { - payloadSchema := JSONSchemaFor[TPayload]() - return bus.On(eventPattern, handlerName, func(event *BaseEvent, ctx context.Context) (any, error) { - if err := jsonschema.Validate(payloadSchema, event.Payload); err != nil { - var zero TResult - return zero, fmt.Errorf("EventHandlerPayloadSchemaError: Event payload did not match declared handler payload type: %w", err) - } - payload, err := EventPayloadAs[TPayload](event) - if err != nil { - var zero TResult - return zero, err - } - switch typed := any(handler).(type) { - case func(TPayload) (TResult, error): - return typed(payload) - case func(TPayload, context.Context) (TResult, error): - return typed(payload, ctx) - case func(TPayload) TResult: - return typed(payload), nil - case func(TPayload, context.Context) TResult: - return typed(payload, ctx), nil - case func(TPayload) error: - var zero TResult - return zero, typed(payload) - case func(TPayload, context.Context) error: - var zero TResult - return zero, typed(payload, ctx) - case func(TPayload): - typed(payload) - var zero TResult - return zero, nil - case func(TPayload, context.Context): - typed(payload, ctx) - var zero TResult - return zero, nil - default: - value := reflect.ValueOf(handler) - var zero TResult - if !value.IsValid() || value.Kind() != reflect.Func || value.IsNil() { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - handlerType := value.Type() - if handlerType.NumIn() != 1 && handlerType.NumIn() != 2 { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - payloadValue, ok := reflectValueForTypedPayload(payload, handlerType.In(0)) - if !ok { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - withContext := handlerType.NumIn() == 2 - if withContext && handlerType.In(1) != contextInterfaceType { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - if handlerType.NumOut() > 2 { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - args := []reflect.Value{payloadValue} - if withContext { - args = append(args, reflect.ValueOf(ctx)) - } - results := value.Call(args) - switch len(results) { - case 0: - return zero, nil - case 1: - if results[0].Type().Implements(errorInterfaceType) { - if reflectValueIsNil(results[0]) { - return zero, nil - } - return zero, results[0].Interface().(error) - } - typedResult, ok := results[0].Interface().(TResult) - if !ok { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - return typedResult, nil - default: - if !results[1].Type().Implements(errorInterfaceType) { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - var err error - if !reflectValueIsNil(results[1]) { - err = results[1].Interface().(error) - } - typedResult, ok := results[0].Interface().(TResult) - if !ok { - return zero, fmt.Errorf("unsupported typed handler signature: %T", handler) - } - return typedResult, err - } - } - }, options) -} - -func reflectValueForTypedPayload(payload any, targetType reflect.Type) (reflect.Value, bool) { - payloadValue := reflect.ValueOf(payload) - if payloadValue.IsValid() { - return payloadValue, payloadValue.Type().AssignableTo(targetType) - } - switch targetType.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice: - return reflect.Zero(targetType), true - default: - return reflect.Value{}, false - } -} - func EventPayloadAs[T any](event *BaseEvent) (T, error) { var payload T if event == nil { diff --git a/docs/api/baseevent.mdx b/docs/api/baseevent.mdx index e45e5dbb..0aadc803 100644 --- a/docs/api/baseevent.mdx +++ b/docs/api/baseevent.mdx @@ -48,10 +48,10 @@ type FooPayload struct { type FooResult string -event, err := abxbus.NewBaseEventWithResult[FooPayload, FooResult]("FooCreateEvent", FooPayload{ +event, err := abxbus.NewEvent[FooPayload]("FooCreateEvent", FooPayload{ Name: "Ada", Age: 37, -}) +}, abxbus.ResultType[FooResult]()) ``` @@ -149,7 +149,7 @@ const value = await completed.eventResult() ```go type MyEvent struct{} -pending := bus.Emit(abxbus.MustNewTypedEvent[MyEvent]("MyEvent", MyEvent{})) +pending := bus.Emit(abxbus.MustNewEvent("MyEvent", MyEvent{})) completed, err := pending.Now() if err != nil { return err diff --git a/docs/api/eventbus.mdx b/docs/api/eventbus.mdx index b5413c47..c4a51d8f 100644 --- a/docs/api/eventbus.mdx +++ b/docs/api/eventbus.mdx @@ -154,10 +154,10 @@ bus.on('*', wildcardHandler) ```go -bus.On("UserEvent", "handler", handler, nil) -bus.On("*", "wildcard_handler", wildcardHandler, nil) +bus.OnEventName("UserEvent", "handler", handler, nil) +bus.OnEventName("*", "wildcard_handler", wildcardHandler, nil) timeout := 5.0 -bus.On("UserEvent", "custom", handler, &abxbus.EventHandler{ +bus.OnEventName("UserEvent", "custom", handler, &abxbus.EventHandler{ HandlerTimeout: &timeout, }) ``` @@ -220,7 +220,7 @@ bus.off('*') ```go -handler := bus.On("UserEvent", "handler", onUserEvent, nil) +handler := bus.OnEventName("UserEvent", "handler", onUserEvent, nil) bus.Off("UserEvent", handler) bus.Off("UserEvent", handler.ID) bus.Off("*", nil) @@ -266,7 +266,7 @@ const result = await event.now({ first_result: true }).eventResult() ```go -event := bus.Emit(abxbus.NewBaseEvent("MyEvent", map[string]any{"data": "x"})) +event := bus.EmitEventName("MyEvent", map[string]any{"data": "x"}) result, err := event.EventResult() if err != nil { return err @@ -321,12 +321,12 @@ const child = await bus.find(ChildEvent, { child_of: parentEvent, future: 5 }) ```go -event, err := bus.Find("ResponseEvent", nil, nil) -future, err := bus.Find("ResponseEvent", nil, &abxbus.FindOptions{ +event, err := bus.FindEventName("ResponseEvent", nil, nil) +future, err := bus.FindEventName("ResponseEvent", nil, &abxbus.FindOptions{ Past: false, Future: 5.0, }) -child, err := bus.Find("ChildEvent", nil, &abxbus.FindOptions{ +child, err := bus.FindEventName("ChildEvent", nil, &abxbus.FindOptions{ ChildOf: parentEvent, Future: 5.0, }) @@ -379,13 +379,13 @@ const recent = await bus.filter(ResponseEvent, { past: 10, future: false, limit: ```go limit := 5 -recent, err := bus.Filter("ResponseEvent", nil, &abxbus.FilterOptions{ +recent, err := bus.FilterEventName("ResponseEvent", nil, &abxbus.FilterOptions{ Past: 10.0, Future: false, Limit: &limit, }) -recentWithPredicate, err := bus.Filter( +recentWithPredicate, err := bus.FilterEventName( "ResponseEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["ok"] == true @@ -597,7 +597,7 @@ await bus.destroy({ clear: true }) ```go type ResumeTickEvent struct{} -resumeTick := abxbus.MustNewTypedEvent[ResumeTickEvent]("ResumeTickEvent", ResumeTickEvent{}) +resumeTick := abxbus.MustNewEvent("ResumeTickEvent", ResumeTickEvent{}) // 1) Serialize full bus state payload, err := bus.ToJSON() @@ -618,9 +618,9 @@ fmt.Println(string(payload)) bus, err = abxbus.EventBusFromJSON(payload) // 3) Re-link runtime callables by handler id -bus.On("UserCreatedEvent", "onUserCreated", onUserCreated, bus.Handlers["018f..."]) -bus.On("UserDeletedEvent", "onUserDeleted", onUserDeleted, bus.Handlers["018g..."]) -bus.On("UserUpdatedEvent", "onUserUpdated", onUserUpdated, bus.Handlers["018h..."]) +bus.OnEventName("UserCreatedEvent", "onUserCreated", onUserCreated, bus.Handlers["018f..."]) +bus.OnEventName("UserDeletedEvent", "onUserDeleted", onUserDeleted, bus.Handlers["018g..."]) +bus.OnEventName("UserUpdatedEvent", "onUserUpdated", onUserUpdated, bus.Handlers["018h..."]) // 4) Resume processing bus.Emit(resumeTick) diff --git a/docs/api/eventhandler.mdx b/docs/api/eventhandler.mdx index 2aab8a37..ba33d593 100644 --- a/docs/api/eventhandler.mdx +++ b/docs/api/eventhandler.mdx @@ -40,7 +40,7 @@ bus.off(MyEvent, entry) ```go -entry := bus.On("MyEvent", "handler", handler, nil) +entry := bus.OnEventName("MyEvent", "handler", handler, nil) bus.Off("MyEvent", entry) ``` diff --git a/docs/concurrency/backpressure.mdx b/docs/concurrency/backpressure.mdx index 6a05bc4e..b9b05013 100644 --- a/docs/concurrency/backpressure.mdx +++ b/docs/concurrency/backpressure.mdx @@ -216,7 +216,7 @@ println!("pending_event_queue={pending_count} event_history={history_count}"); ```go -event := bus.Emit(abxbus.NewBaseEvent("MyEvent", nil)) +event := bus.EmitEventName("MyEvent", nil) var state struct { PendingEventQueue []string `json:"pending_event_queue"` diff --git a/docs/concurrency/events-bus-serial.mdx b/docs/concurrency/events-bus-serial.mdx index 05438076..4d963108 100644 --- a/docs/concurrency/events-bus-serial.mdx +++ b/docs/concurrency/events-bus-serial.mdx @@ -155,12 +155,12 @@ func main() { } } - busA.On("WorkEvent", "handler_a", handler(&startsA), nil) - busB.On("WorkEvent", "handler_b", handler(&startsB), nil) + busA.OnEventName("WorkEvent", "handler_a", handler(&startsA), nil) + busB.OnEventName("WorkEvent", "handler_b", handler(&startsB), nil) for i := 0; i < 4; i++ { - busA.Emit(abxbus.NewBaseEvent("WorkEvent", map[string]any{"order": i, "source": "a"})) - busB.Emit(abxbus.NewBaseEvent("WorkEvent", map[string]any{"order": i, "source": "b"})) + busA.EmitEventName("WorkEvent", map[string]any{"order": i, "source": "a"}) + busB.EmitEventName("WorkEvent", map[string]any{"order": i, "source": "b"}) } busA.WaitUntilIdle(nil) diff --git a/docs/concurrency/events-global-serial.mdx b/docs/concurrency/events-global-serial.mdx index 8ed50cdd..12f8f847 100644 --- a/docs/concurrency/events-global-serial.mdx +++ b/docs/concurrency/events-global-serial.mdx @@ -142,12 +142,12 @@ func main() { return nil, nil } - busA.On("SerialEvent", "handler", handler, nil) - busB.On("SerialEvent", "handler", handler, nil) + busA.OnEventName("SerialEvent", "handler", handler, nil) + busB.OnEventName("SerialEvent", "handler", handler, nil) for i := 0; i < 3; i++ { - busA.Emit(abxbus.NewBaseEvent("SerialEvent", map[string]any{"order": i, "source": "a"})) - busB.Emit(abxbus.NewBaseEvent("SerialEvent", map[string]any{"order": i, "source": "b"})) + busA.EmitEventName("SerialEvent", map[string]any{"order": i, "source": "a"}) + busB.EmitEventName("SerialEvent", map[string]any{"order": i, "source": "b"}) } busA.WaitUntilIdle(nil) diff --git a/docs/concurrency/events-parallel.mdx b/docs/concurrency/events-parallel.mdx index cc61a2ea..38c42c36 100644 --- a/docs/concurrency/events-parallel.mdx +++ b/docs/concurrency/events-parallel.mdx @@ -117,7 +117,7 @@ func main() { maxInFlight := 0 release := make(chan struct{}) - bus.On("ParallelEvent", "handler", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("ParallelEvent", "handler", func(event *abxbus.BaseEvent) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -134,8 +134,8 @@ func main() { return nil, nil }, nil) - bus.Emit(abxbus.NewBaseEvent("ParallelEvent", map[string]any{"order": 0})) - bus.Emit(abxbus.NewBaseEvent("ParallelEvent", map[string]any{"order": 1})) + bus.EmitEventName("ParallelEvent", map[string]any{"order": 0}) + bus.EmitEventName("ParallelEvent", map[string]any{"order": 1}) time.Sleep(10 * time.Millisecond) close(release) diff --git a/docs/concurrency/handler-completion-all.mdx b/docs/concurrency/handler-completion-all.mdx index 8da7e233..188cc3d1 100644 --- a/docs/concurrency/handler-completion-all.mdx +++ b/docs/concurrency/handler-completion-all.mdx @@ -112,7 +112,7 @@ func main() { var mu sync.Mutex seen := map[string]bool{} - bus.On("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { time.Sleep(10 * time.Millisecond) mu.Lock() seen["fast"] = true @@ -120,7 +120,7 @@ func main() { return "fast", nil }, nil) - bus.On("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { time.Sleep(50 * time.Millisecond) mu.Lock() seen["slow"] = true @@ -128,7 +128,7 @@ func main() { return "slow", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("CompletionEvent", nil)) + event := bus.EmitEventName("CompletionEvent", nil) if _, err := event.Now(); err != nil { panic(err) } diff --git a/docs/concurrency/handler-completion-first.mdx b/docs/concurrency/handler-completion-first.mdx index 428d0411..2eab8bc7 100644 --- a/docs/concurrency/handler-completion-first.mdx +++ b/docs/concurrency/handler-completion-first.mdx @@ -117,19 +117,19 @@ func main() { slowStarted := make(chan struct{}, 1) slowCompleted := make(chan struct{}, 1) - bus.On("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { slowStarted <- struct{}{} time.Sleep(500 * time.Millisecond) slowCompleted <- struct{}{} return "slow", nil }, nil) - bus.On("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { time.Sleep(10 * time.Millisecond) return "winner", nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("CompletionEvent", nil)) + event := bus.EmitEventName("CompletionEvent", nil) _, err := event.Now(&abxbus.EventWaitOptions{FirstResult: true}) if err != nil { panic(err) diff --git a/docs/concurrency/handlers-parallel.mdx b/docs/concurrency/handlers-parallel.mdx index 6952782b..a9ab6008 100644 --- a/docs/concurrency/handlers-parallel.mdx +++ b/docs/concurrency/handlers-parallel.mdx @@ -126,10 +126,10 @@ func main() { return nil, nil } - bus.On("HandlerEvent", "tracked_a", tracked, nil) - bus.On("HandlerEvent", "tracked_b", tracked, nil) + bus.OnEventName("HandlerEvent", "tracked_a", tracked, nil) + bus.OnEventName("HandlerEvent", "tracked_b", tracked, nil) - event := bus.Emit(abxbus.NewBaseEvent("HandlerEvent", nil)) + event := bus.EmitEventName("HandlerEvent", nil) <-started <-started close(release) diff --git a/docs/concurrency/handlers-serial.mdx b/docs/concurrency/handlers-serial.mdx index b549c25b..46d9f03b 100644 --- a/docs/concurrency/handlers-serial.mdx +++ b/docs/concurrency/handlers-serial.mdx @@ -97,21 +97,21 @@ func main() { }) log := []string{} - bus.On("HandlerEvent", "h1", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("HandlerEvent", "h1", func(event *abxbus.BaseEvent) (any, error) { log = append(log, "h1_start") time.Sleep(10 * time.Millisecond) log = append(log, "h1_end") return nil, nil }, nil) - bus.On("HandlerEvent", "h2", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("HandlerEvent", "h2", func(event *abxbus.BaseEvent) (any, error) { log = append(log, "h2_start") time.Sleep(10 * time.Millisecond) log = append(log, "h2_end") return nil, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("HandlerEvent", nil)) + event := bus.EmitEventName("HandlerEvent", nil) if _, err := event.Now(); err != nil { panic(err) } diff --git a/docs/concurrency/immediate-execution.mdx b/docs/concurrency/immediate-execution.mdx index 9be935d1..e0eda6aa 100644 --- a/docs/concurrency/immediate-execution.mdx +++ b/docs/concurrency/immediate-execution.mdx @@ -102,8 +102,8 @@ bus.on(ChildEvent, |_event: ChildEvent| async move { ```go bus := abxbus.NewEventBus("RpcBus", nil) -bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { - child := event.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) +bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { + child := event.EmitEventName("ChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } @@ -114,7 +114,7 @@ bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("parent got: %v", value), nil }, nil) -bus.On("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { return "child response", nil }, nil) ``` @@ -202,11 +202,11 @@ bus := abxbus.NewEventBus("ParallelRpcBus", &abxbus.EventBusOptions{ EventConcurrency: abxbus.EventConcurrencyParallel, }) -bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { children := []*abxbus.BaseEvent{ - event.Emit(abxbus.NewBaseEvent("SomeChildEvent1", nil)), - event.Emit(abxbus.NewBaseEvent("SomeChildEvent2", nil)), - event.Emit(abxbus.NewBaseEvent("SomeChildEvent3", nil)), + event.EmitEventName("SomeChildEvent1", nil), + event.EmitEventName("SomeChildEvent2", nil), + event.EmitEventName("SomeChildEvent3", nil), } for _, child := range children { @@ -363,11 +363,11 @@ bus := abxbus.NewEventBus("OrderBus", &abxbus.EventBusOptions{ }) order := []string{} -bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { order = append(order, "parent_start") // Detached top-level work: no parent link is recorded for the sibling. - bus.Emit(abxbus.NewBaseEvent("SiblingEvent", nil)) - child := event.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) + bus.EmitEventName("SiblingEvent", nil) + child := event.EmitEventName("ChildEvent", nil) if _, err := child.Now(); err != nil { return nil, err } @@ -375,17 +375,17 @@ bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { return nil, nil }, nil) -bus.On("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { order = append(order, "child") return nil, nil }, nil) -bus.On("SiblingEvent", "on_sibling", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("SiblingEvent", "on_sibling", func(event *abxbus.BaseEvent) (any, error) { order = append(order, "sibling") return nil, nil }, nil) -parent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) +parent := bus.EmitEventName("ParentEvent", nil) if _, err := parent.Now(); err != nil { panic(err) } diff --git a/docs/concurrency/timeouts.mdx b/docs/concurrency/timeouts.mdx index 25cb9ca9..ba9e9d0c 100644 --- a/docs/concurrency/timeouts.mdx +++ b/docs/concurrency/timeouts.mdx @@ -213,7 +213,7 @@ bus.on(WorkEvent, slowHandler, { ```go -entry := bus.On("WorkEvent", "slow_handler", slowHandler, nil) +entry := bus.OnEventName("WorkEvent", "slow_handler", slowHandler, nil) handlerTimeout := 1.5 handlerSlowTimeout := 0.5 entry.HandlerTimeout = &handlerTimeout diff --git a/docs/features/async-sync-handlers.mdx b/docs/features/async-sync-handlers.mdx index a67aa0f6..6854a6c3 100644 --- a/docs/features/async-sync-handlers.mdx +++ b/docs/features/async-sync-handlers.mdx @@ -198,9 +198,9 @@ func main() { bus := abxbus.NewEventBus("AppBus", nil) handlers := &HandlerSet{Prefix: "svc"} - bus.On("WorkEvent", "bare_handler", bareHandler, nil) - bus.On("WorkEvent", "static_style_handler", StaticStyleHandler, nil) - bus.On("WorkEvent", "instance_handler", handlers.InstanceHandler, nil) + bus.OnEventName("WorkEvent", "bare_handler", bareHandler, nil) + bus.OnEventName("WorkEvent", "static_style_handler", StaticStyleHandler, nil) + bus.OnEventName("WorkEvent", "instance_handler", handlers.InstanceHandler, nil) } ``` diff --git a/docs/features/context-propagation.mdx b/docs/features/context-propagation.mdx index 32fcb10a..b505a8b8 100644 --- a/docs/features/context-propagation.mdx +++ b/docs/features/context-propagation.mdx @@ -120,14 +120,14 @@ func main() { requestIDKey := contextKey("request_id") bus := abxbus.NewEventBus("AppBus", nil) - bus.On("RequestEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.OnEventName("RequestEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { fmt.Println(ctx.Value(requestIDKey)) // req-123 return nil, nil }, nil) ctx := context.WithValue(context.Background(), requestIDKey, "req-123") - if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("RequestEvent", nil)).Now(); err != nil { + if _, err := bus.EmitEventNameWithContext(ctx, "RequestEvent", nil).Now(); err != nil { panic(err) } } @@ -179,7 +179,7 @@ block_on(event.now()); ```go // net/http-style shape (conceptual) ctx := context.WithValue(req.Context(), requestIDKey, req.Header.Get("x-request-id")) -if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("RequestEvent", nil)).Now(); err != nil { +if _, err := bus.EmitEventNameWithContext(ctx, "RequestEvent", nil).Now(); err != nil { panic(err) } // handlers can still read ctx.Value(requestIDKey) diff --git a/docs/features/event-debouncing.mdx b/docs/features/event-debouncing.mdx index 7fed4238..76fed787 100644 --- a/docs/features/event-debouncing.mdx +++ b/docs/features/event-debouncing.mdx @@ -101,7 +101,7 @@ let result = block_on(event.event_result())?; ```go -existing, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { +existing, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["url"] == url }, &abxbus.FindOptions{ Past: 10.0, // look back 10s @@ -113,7 +113,7 @@ if err != nil { event := existing if event == nil { - event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) + event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) } if _, err := event.Now(); err != nil { panic(err) @@ -186,7 +186,7 @@ let result = block_on(event.event_result())?; ```go -inFlight, err := bus.Find("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { +inFlight, err := bus.FindEventName("ScreenshotEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["url"] == url }, &abxbus.FindOptions{ Past: false, // skip history @@ -198,7 +198,7 @@ if err != nil { event := inFlight if event == nil { - event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) + event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) } if _, err := event.Now(); err != nil { panic(err) @@ -285,18 +285,18 @@ sameURL := func(event *abxbus.BaseEvent) bool { return event.Payload["url"] == url } -event, err := bus.Find("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: 10.0, Future: false}) +event, err := bus.FindEventName("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: 10.0, Future: false}) if err != nil { panic(err) } if event == nil { - event, err = bus.Find("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: false, Future: 2.0}) + event, err = bus.FindEventName("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: false, Future: 2.0}) if err != nil { panic(err) } } if event == nil { - event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) + event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) } if _, err := event.Now(); err != nil { @@ -385,18 +385,18 @@ func emitDebouncedScreenshot(ctx context.Context, bus *abxbus.EventBus, url stri return event.Payload["url"] == url } - event, err := bus.Find("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: 15.0, Future: false}) + event, err := bus.FindEventName("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: 15.0, Future: false}) if err != nil { return nil, err } if event == nil { - event, err = bus.Find("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: false, Future: 3.0}) + event, err = bus.FindEventName("ScreenshotEvent", sameURL, &abxbus.FindOptions{Past: false, Future: 3.0}) if err != nil { return nil, err } } if event == nil { - event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) + event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) } if _, err := event.Now(); err != nil { diff --git a/docs/features/event-history-store.mdx b/docs/features/event-history-store.mdx index b6fdebd7..1e1eb037 100644 --- a/docs/features/event-history-store.mdx +++ b/docs/features/event-history-store.mdx @@ -161,7 +161,7 @@ console.log('after completion -> pending_event_queue=', bus.pending_event_queue. ```go -event := bus.Emit(abxbus.NewBaseEvent("MyEvent", nil)) +event := bus.EmitEventName("MyEvent", nil) var before struct { PendingEventQueue []string `json:"pending_event_queue"` diff --git a/docs/features/event-pattern-matching.mdx b/docs/features/event-pattern-matching.mdx index c2bab860..cfd264bf 100644 --- a/docs/features/event-pattern-matching.mdx +++ b/docs/features/event-pattern-matching.mdx @@ -14,7 +14,7 @@ Both accept the same pattern forms: - string event type name - `'*'` wildcard (match everything) -Go and Rust use string event type names for low-level registration/lookup, plus typed helpers (`OnTyped[...]` in Go, `EventSpec`/`BaseEvent` in Rust) when you want static payload/result typing. +Go and Rust use string event type names for low-level registration/lookup, plus typed payload/event APIs (`bus.On(...)` in Go, `EventSpec`/`BaseEvent` in Rust) when you want payload/result validation. ## Supported pattern forms @@ -161,8 +161,7 @@ type UserActionPayload struct { func main() { bus := abxbus.NewEventBus("AppBus", nil) - abxbus.OnTyped[UserActionPayload, string]( - bus, + bus.On( "UserActionEvent", "on", func(payload UserActionPayload) (string, error) { @@ -171,21 +170,22 @@ func main() { nil, ) - bus.On("UserActionEvent", "on_by_name", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("UserActionEvent", "on_by_name", func(event *abxbus.BaseEvent) (any, error) { fmt.Println("by-name", event.EventType, event.Payload["action"]) // by-name UserActionEvent click return nil, nil }, nil) - bus.On("*", "on_any", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("*", "on_any", func(event *abxbus.BaseEvent) (any, error) { fmt.Println("wildcard", event.EventType) // wildcard UserActionEvent return nil, nil }, nil) - event, err := abxbus.NewBaseEventWithResult[UserActionPayload, string]( + event, err := abxbus.NewEvent[UserActionPayload]( "UserActionEvent", UserActionPayload{Action: "click"}, + abxbus.ResultType[string](), ) if err != nil { panic(err) @@ -195,11 +195,11 @@ func main() { panic(err) } - namedMatch, err := bus.Find("UserActionEvent", nil, nil) + namedMatch, err := bus.FindEventName("UserActionEvent", nil, nil) if err != nil { panic(err) } - wildcardMatch, err := bus.Find("*", nil, &abxbus.FindOptions{Future: 5.0}) + wildcardMatch, err := bus.FindEventName("*", nil, &abxbus.FindOptions{Future: 5.0}) if err != nil { panic(err) } @@ -223,6 +223,6 @@ String keys and `'*'` are intentionally looser: - Python: treat as `BaseEvent[Any]` - TypeScript: typed as base `BaseEvent`/unknown-oriented handler return checks - Rust: typed handlers use `bus.on(MyEvent, ...)`; raw string/wildcard registration is reserved for low-level forwarding internals. -- Go: typed handlers use `OnTyped[...]`; string/wildcard handlers receive `*BaseEvent` +- Go: typed handlers use `bus.On(...)`; string/wildcard handlers use `bus.OnEventName(...)` and receive `*BaseEvent` Use string/wildcard patterns when you need dynamic behavior. Use classes whenever you want strict payload/result type hints through handlers and lookups. diff --git a/docs/features/fifo-processing.mdx b/docs/features/fifo-processing.mdx index 70847848..91114826 100644 --- a/docs/features/fifo-processing.mdx +++ b/docs/features/fifo-processing.mdx @@ -132,7 +132,7 @@ func main() { startedOrder := []int{} completedOrder := []int{} - bus.On("JobEvent", "on_job", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("JobEvent", "on_job", func(event *abxbus.BaseEvent) (any, error) { order := event.Payload["order"].(int) delayMS := event.Payload["delay_ms"].(int) startedOrder = append(startedOrder, order) @@ -142,9 +142,9 @@ func main() { }, nil) emitted := []*abxbus.BaseEvent{ - bus.Emit(abxbus.NewBaseEvent("JobEvent", map[string]any{"order": 0, "delay_ms": 30})), - bus.Emit(abxbus.NewBaseEvent("JobEvent", map[string]any{"order": 1, "delay_ms": 1})), - bus.Emit(abxbus.NewBaseEvent("JobEvent", map[string]any{"order": 2, "delay_ms": 20})), + bus.EmitEventName("JobEvent", map[string]any{"order": 0, "delay_ms": 30}), + bus.EmitEventName("JobEvent", map[string]any{"order": 1, "delay_ms": 1}), + bus.EmitEventName("JobEvent", map[string]any{"order": 2, "delay_ms": 20}), } bus.WaitUntilIdle(nil) @@ -306,22 +306,22 @@ console.log(treeLines) bus := abxbus.NewEventBus("FifoBus", nil) trace := []string{} -bus.On("SlowEvent", "on_slow", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("SlowEvent", "on_slow", func(event *abxbus.BaseEvent) (any, error) { trace = append(trace, fmt.Sprintf("start:%s:%s", event.EventType, event.Payload["name"])) time.Sleep(40 * time.Millisecond) trace = append(trace, fmt.Sprintf("end:%s:%s", event.EventType, event.Payload["name"])) return nil, nil }, nil) -bus.On("FastEvent", "on_fast", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("FastEvent", "on_fast", func(event *abxbus.BaseEvent) (any, error) { trace = append(trace, fmt.Sprintf("start:%s:%s", event.EventType, event.Payload["name"])) time.Sleep(1 * time.Millisecond) trace = append(trace, fmt.Sprintf("end:%s:%s", event.EventType, event.Payload["name"])) return nil, nil }, nil) -slow := bus.Emit(abxbus.NewBaseEvent("SlowEvent", map[string]any{"name": "slow-a"})) -fast := bus.Emit(abxbus.NewBaseEvent("FastEvent", map[string]any{"name": "fast-b"})) +slow := bus.EmitEventName("SlowEvent", map[string]any{"name": "slow-a"}) +fast := bus.EmitEventName("FastEvent", map[string]any{"name": "fast-b"}) bus.WaitUntilIdle(nil) fmt.Println(trace) diff --git a/docs/features/find-events.mdx b/docs/features/find-events.mdx index 1e51e617..be955574 100644 --- a/docs/features/find-events.mdx +++ b/docs/features/find-events.mdx @@ -41,7 +41,7 @@ await bus.find(event_pattern, where, options?) ```go -bus.Find( +bus.FindEventName( "ResponseEvent", // event type string or "*" func(event *abxbus.BaseEvent) bool { // optional predicate return true @@ -130,7 +130,7 @@ const existing = await bus.find(ResponseEvent) ```go -existing, err := bus.Find("ResponseEvent", nil, nil) +existing, err := bus.FindEventName("ResponseEvent", nil, nil) ``` @@ -163,7 +163,7 @@ const future = await bus.find(ResponseEvent, { past: false, future: 5 }) ```go -future, err := bus.Find("ResponseEvent", nil, &abxbus.FindOptions{ +future, err := bus.FindEventName("ResponseEvent", nil, &abxbus.FindOptions{ Past: false, Future: 5.0, }) @@ -199,7 +199,7 @@ const match = await bus.find(ResponseEvent, { past: 5, future: 5 }) ```go -match, err := bus.Find("ResponseEvent", nil, &abxbus.FindOptions{ +match, err := bus.FindEventName("ResponseEvent", nil, &abxbus.FindOptions{ Past: 5.0, Future: 5.0, }) @@ -251,7 +251,7 @@ const match = await bus.find( ```go -match, err := bus.Find( +match, err := bus.FindEventName( "ResponseEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["request_id"] == myID @@ -312,7 +312,7 @@ const anyCompleted = await bus.find( ```go -anyCompleted, err := bus.Find( +anyCompleted, err := bus.FindEventName( "*", func(event *abxbus.BaseEvent) bool { return strings.HasSuffix(event.EventType, "ResultEvent") @@ -373,13 +373,13 @@ const child = await bus.find(TabCreatedEvent, { child_of: parentEvent, past: 5 } ```go -parentEvent := bus.Emit(abxbus.NewBaseEvent("NavigateToUrlEvent", map[string]any{ +parentEvent := bus.EmitEventName("NavigateToUrlEvent", map[string]any{ "url": "https://example.com", -})) +}) if _, err := parentEvent.Now(); err != nil { panic(err) } -child, err := bus.Find("TabCreatedEvent", nil, &abxbus.FindOptions{ +child, err := bus.FindEventName("TabCreatedEvent", nil, &abxbus.FindOptions{ ChildOf: parentEvent, Past: 5.0, }) @@ -452,18 +452,18 @@ await event.now() ```go -event, err := bus.Find("ScreenshotEvent", nil, &abxbus.FindOptions{Past: 10.0, Future: false}) +event, err := bus.FindEventName("ScreenshotEvent", nil, &abxbus.FindOptions{Past: 10.0, Future: false}) if err != nil { panic(err) } if event == nil { - event, err = bus.Find("ScreenshotEvent", nil, &abxbus.FindOptions{Past: false, Future: 5.0}) + event, err = bus.FindEventName("ScreenshotEvent", nil, &abxbus.FindOptions{Past: false, Future: 5.0}) if err != nil { panic(err) } } if event == nil { - event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", nil)) + event = bus.EmitEventName("ScreenshotEvent", nil) } if _, err := event.Now(); err != nil { panic(err) @@ -540,7 +540,7 @@ const recent = await bus.filter(ResponseEvent, { past: 10, future: false, limit: ```go limit := 5 -recent, err := bus.Filter("ResponseEvent", nil, &abxbus.FilterOptions{ +recent, err := bus.FilterEventName("ResponseEvent", nil, &abxbus.FilterOptions{ Past: 10.0, Future: false, Limit: &limit, diff --git a/docs/features/forwarding-between-buses.mdx b/docs/features/forwarding-between-buses.mdx index ecede09b..60fdba5c 100644 --- a/docs/features/forwarding-between-buses.mdx +++ b/docs/features/forwarding-between-buses.mdx @@ -274,21 +274,21 @@ func main() { MaxHistorySize: &maxHistory, })} - auth.bus.On("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { + auth.bus.OnEventName("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("auth-ok:%s", event.Payload["user_id"]), nil }, nil) - billing.bus.On("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { + billing.bus.OnEventName("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("billing-ok:%s", event.Payload["user_id"]), nil }, nil) - auth.bus.On("*", "forward_to_relay", func(event *abxbus.BaseEvent) (any, error) { + auth.bus.OnEventName("*", "forward_to_relay", func(event *abxbus.BaseEvent) (any, error) { return relay.bus.Emit(event), nil }, nil) - relay.bus.On("*", "forward_to_billing", func(event *abxbus.BaseEvent) (any, error) { + relay.bus.OnEventName("*", "forward_to_billing", func(event *abxbus.BaseEvent) (any, error) { return billing.bus.Emit(event), nil }, nil) - event := auth.bus.Emit(abxbus.NewBaseEvent("UserCreatedEvent", map[string]any{"user_id": "u-a8d1"})) + event := auth.bus.EmitEventName("UserCreatedEvent", map[string]any{"user_id": "u-a8d1"}) result, err := event.EventResult() if err != nil { panic(err) @@ -378,12 +378,12 @@ left := abxbus.NewEventBus("LeftBus", nil) right := abxbus.NewEventBus("RightBus", nil) // uni-directional -left.On("*", "forward_to_right", func(event *abxbus.BaseEvent) (any, error) { +left.OnEventName("*", "forward_to_right", func(event *abxbus.BaseEvent) (any, error) { return right.Emit(event), nil }, nil) // bi-directional (add reverse path) -right.On("*", "forward_to_left", func(event *abxbus.BaseEvent) (any, error) { +right.OnEventName("*", "forward_to_left", func(event *abxbus.BaseEvent) (any, error) { return left.Emit(event), nil }, nil) ``` @@ -509,17 +509,17 @@ busB := abxbus.NewEventBus("BusB", nil) busC := abxbus.NewEventBus("BusC", nil) // cycle: A -> B -> C -> A -busA.On("*", "forward_to_b", func(event *abxbus.BaseEvent) (any, error) { +busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent) (any, error) { return busB.Emit(event), nil }, nil) -busB.On("*", "forward_to_c", func(event *abxbus.BaseEvent) (any, error) { +busB.OnEventName("*", "forward_to_c", func(event *abxbus.BaseEvent) (any, error) { return busC.Emit(event), nil }, nil) -busC.On("*", "forward_to_a", func(event *abxbus.BaseEvent) (any, error) { +busC.OnEventName("*", "forward_to_a", func(event *abxbus.BaseEvent) (any, error) { return busA.Emit(event), nil }, nil) -event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"message": "hello"})) +event := busA.EmitEventName("PingEvent", map[string]any{"message": "hello"}) if _, err := event.Now(); err != nil { panic(err) } diff --git a/docs/features/parent-child-tracking.mdx b/docs/features/parent-child-tracking.mdx index 2f2b465e..8a132a36 100644 --- a/docs/features/parent-child-tracking.mdx +++ b/docs/features/parent-child-tracking.mdx @@ -44,9 +44,9 @@ In Rust, the same split is explicit: In Go, the same split is explicit: -- `child := event.Emit(abxbus.NewBaseEvent(...))` creates linked child work. +- `child := event.EmitEventName(...)` creates linked child work. - `child.Now()` queue-jumps and waits for that linked child. -- `bus.Emit(abxbus.NewBaseEvent(...))` creates detached top-level work. +- `bus.EmitEventName(...)` creates detached top-level work. - calling `Now()` on a bus-emitted event waits for it without adding parent-child lineage. ## Works across forwarded buses too @@ -293,10 +293,10 @@ import ( func main() { bus := abxbus.NewEventBus("TreeBus", nil) - bus.On("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { orderID := event.Payload["order_id"].(string) - reserve := event.Emit(abxbus.NewBaseEvent("ReserveInventoryEvent", map[string]any{"order_id": orderID})) + reserve := event.EmitEventName("ReserveInventoryEvent", map[string]any{"order_id": orderID}) if _, err := reserve.Now(); err != nil { return nil, err } @@ -305,7 +305,7 @@ func main() { return nil, err } - charge := event.Emit(abxbus.NewBaseEvent("ChargeCardEvent", map[string]any{"order_id": orderID})) + charge := event.EmitEventName("ChargeCardEvent", map[string]any{"order_id": orderID}) if _, err := charge.Now(); err != nil { return nil, err } @@ -314,7 +314,7 @@ func main() { return nil, err } - receipt := event.Emit(abxbus.NewBaseEvent("SendReceiptEvent", map[string]any{"order_id": orderID})) + receipt := event.EmitEventName("SendReceiptEvent", map[string]any{"order_id": orderID}) if _, err := receipt.Now(); err != nil { return nil, err } @@ -326,13 +326,13 @@ func main() { return fmt.Sprintf("%v|%v|%v", reserveID, chargeID, receiptID), nil }, nil) - bus.On("ReserveInventoryEvent", "on_reserve", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("ReserveInventoryEvent", "on_reserve", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("reserve:%s", event.Payload["order_id"]), nil }, nil) - bus.On("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { orderID := event.Payload["order_id"].(string) - fraud := event.Emit(abxbus.NewBaseEvent("FraudCheckEvent", map[string]any{"order_id": orderID})) + fraud := event.EmitEventName("FraudCheckEvent", map[string]any{"order_id": orderID}) if _, err := fraud.Now(); err != nil { return nil, err } @@ -343,14 +343,14 @@ func main() { return fmt.Sprintf("charge:%s:%v", orderID, fraudStatus), nil }, nil) - bus.On("FraudCheckEvent", "on_fraud", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("FraudCheckEvent", "on_fraud", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("fraud-ok:%s", event.Payload["order_id"]), nil }, nil) - bus.On("SendReceiptEvent", "on_receipt", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("SendReceiptEvent", "on_receipt", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("receipt:%s", event.Payload["order_id"]), nil }, nil) - root := bus.Emit(abxbus.NewBaseEvent("CheckoutEvent", map[string]any{"order_id": "ord-123"})) + root := bus.EmitEventName("CheckoutEvent", map[string]any{"order_id": "ord-123"}) result, err := root.EventResult() if err != nil { panic(err) diff --git a/docs/features/return-value-handling.mdx b/docs/features/return-value-handling.mdx index d9debaf9..115d72b2 100644 --- a/docs/features/return-value-handling.mdx +++ b/docs/features/return-value-handling.mdx @@ -93,8 +93,7 @@ type DoMathPayload struct { } bus := abxbus.NewEventBus("AppBus", nil) -abxbus.OnTyped[DoMathPayload, int]( - bus, +bus.On( "DoMathEvent", "add", func(payload DoMathPayload) (int, error) { @@ -103,9 +102,10 @@ abxbus.OnTyped[DoMathPayload, int]( nil, ) -event, err := abxbus.NewBaseEventWithResult[DoMathPayload, int]( +event, err := abxbus.NewEvent[DoMathPayload]( "DoMathEvent", DoMathPayload{A: 2, B: 3}, + abxbus.ResultType[int](), ) if err != nil { panic(err) @@ -177,7 +177,7 @@ let values = block_on(event.event_results_list_with_options(EventResultOptions { ```go -event := bus.Emit(abxbus.NewBaseEvent("GetConfigEvent", nil)) +event := bus.EmitEventName("GetConfigEvent", nil) values, err := event.EventResultsList( &abxbus.EventResultOptions{RaiseIfAny: false, RaiseIfNone: false}, ) diff --git a/docs/features/typed-events.mdx b/docs/features/typed-events.mdx index bcbce473..f4b95ad4 100644 --- a/docs/features/typed-events.mdx +++ b/docs/features/typed-events.mdx @@ -103,8 +103,7 @@ type OrderResult struct { } bus := abxbus.NewEventBus("OrdersBus", nil) -abxbus.OnTyped[OrderCreatedPayload, OrderResult]( - bus, +bus.On( "OrderCreatedEvent", "handle_order", func(payload OrderCreatedPayload) (OrderResult, error) { @@ -113,11 +112,11 @@ abxbus.OnTyped[OrderCreatedPayload, OrderResult]( nil, ) -event, err := abxbus.NewBaseEventWithResult[OrderCreatedPayload, OrderResult]("OrderCreatedEvent", OrderCreatedPayload{ +event, err := abxbus.NewEvent[OrderCreatedPayload]("OrderCreatedEvent", OrderCreatedPayload{ OrderID: "order-123", CustomerID: "customer-456", TotalAmount: 42.50, -}) +}, abxbus.ResultType[OrderResult]()) if err != nil { panic(err) } diff --git a/docs/further-reading/events-suck.mdx b/docs/further-reading/events-suck.mdx index 5a1f27fb..3d104f98 100644 --- a/docs/further-reading/events-suck.mdx +++ b/docs/further-reading/events-suck.mdx @@ -59,10 +59,10 @@ const updated = await client.update({ id: id ?? 'fallback-id', age: 46 }, { sour // events_suck is not implemented in abxbus-go yet. // // Use the core EventBus APIs directly: -event := bus.Emit(abxbus.NewBaseEvent("CreateUserEvent", map[string]any{ +event := bus.EmitEventName("CreateUserEvent", map[string]any{ "name": "bob", "age": 45, -})) +}) userID, err := event.EventResult() ``` @@ -179,7 +179,7 @@ const updated = await client.update({ id: user_id ?? 'fallback-id', age: 46 }, { ```go // events_suck.wrap/make_events/make_handler are not implemented in Go yet. -// For typed event APIs, use OnTyped[...] and NewBaseEventWithResult[...]. +// For typed event APIs, use bus.On(...) and NewEvent(..., ResultType[T]()). ``` @@ -259,16 +259,16 @@ bus.on(ChargeCardEvent, async (event) => `receipt-${event.order_id}`) ```go -bus.On("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { orderID, _ := event.Payload["order_id"].(string) - child := event.Emit(abxbus.NewBaseEvent("ChargeCardEvent", map[string]any{"order_id": orderID})) + child := event.EmitEventName("ChargeCardEvent", map[string]any{"order_id": orderID}) if _, err := child.Now(); err != nil { return nil, err } return child.EventResult() }, nil) -bus.On("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { orderID, _ := event.Payload["order_id"].(string) return "receipt-" + orderID, nil }, nil) diff --git a/docs/index.mdx b/docs/index.mdx index 08b71bda..6e7fb25d 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -100,12 +100,12 @@ import ( func main() { bus := abxbus.NewEventBus("MyBus", nil) - bus.On("SomeEvent", "on_some_event", func(event *abxbus.BaseEvent) (any, error) { + bus.OnEventName("SomeEvent", "on_some_event", func(event *abxbus.BaseEvent) (any, error) { fmt.Println(event.Payload["some_data"]) return nil, nil }, nil) - event := bus.Emit(abxbus.NewBaseEvent("SomeEvent", map[string]any{"some_data": 132})) + event := bus.EmitEventName("SomeEvent", map[string]any{"some_data": 132}) _, _ = event.Now() } ``` diff --git a/docs/integrations/bridge-jsonl.mdx b/docs/integrations/bridge-jsonl.mdx index 50ccd88c..ab17acf5 100644 --- a/docs/integrations/bridge-jsonl.mdx +++ b/docs/integrations/bridge-jsonl.mdx @@ -88,10 +88,10 @@ bridge.on('*', bus.emit) bus := abxbus.NewEventBus("AppBus", nil) bridge := abxbus.NewJSONLEventBridge("/tmp/abxbus_events.jsonl", 0.25, "JsonlBridge") -bus.On("*", "jsonl_emit", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("*", "jsonl_emit", func(event *abxbus.BaseEvent) (any, error) { return bridge.Emit(event) }, nil) -bridge.On("*", "bus_emit", func(event *abxbus.BaseEvent) (any, error) { +bridge.OnEventName("*", "bus_emit", func(event *abxbus.BaseEvent) (any, error) { return bus.Emit(event), nil }, nil) ``` diff --git a/docs/integrations/bridges.mdx b/docs/integrations/bridges.mdx index dafdc99b..3c0285a3 100644 --- a/docs/integrations/bridges.mdx +++ b/docs/integrations/bridges.mdx @@ -48,10 +48,10 @@ bridge.on('*', bus.emit) bus := abxbus.NewEventBus("AppBus", nil) bridge := abxbus.NewJSONLEventBridge("/tmp/abxbus_events.jsonl", 0.25, "JsonlBridge") -bus.On("*", "jsonl_emit", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("*", "jsonl_emit", func(event *abxbus.BaseEvent) (any, error) { return bridge.Emit(event) }, nil) -bridge.On("*", "bus_emit", func(event *abxbus.BaseEvent) (any, error) { +bridge.OnEventName("*", "bus_emit", func(event *abxbus.BaseEvent) (any, error) { return bus.Emit(event), nil }, nil) ``` diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 28b75f4f..27981c85 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -135,13 +135,13 @@ block_on(async { ```go bus := abxbus.NewEventBus("MyAuthEventBus", nil) -bus.On("CreateUserEvent", "on_create_user", func(event *abxbus.BaseEvent) (any, error) { +bus.OnEventName("CreateUserEvent", "on_create_user", func(event *abxbus.BaseEvent) (any, error) { return map[string]any{"user_id": "some-user-uuid"}, nil }, nil) -event := bus.Emit(abxbus.NewBaseEvent("CreateUserEvent", map[string]any{ +event := bus.EmitEventName("CreateUserEvent", map[string]any{ "email": "someuser@example.com", -})) +}) result, err := event.EventResult() if err != nil { panic(err) From 5bcd08a8e0c07c9d38bdb38298b1571bde2336fb Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Wed, 13 May 2026 12:19:30 -0700 Subject: [PATCH 2/5] Tighten Go typed event API --- abxbus-go/base_event.go | 8 - abxbus-go/event_bus.go | 116 +++++++++- abxbus-go/jsonl_bridge.go | 9 +- abxbus-go/tests/base_event_test.go | 218 +++++++++--------- .../tests/comprehensive_patterns_test.go | 70 +++--- .../tests/cross_runtime_roundtrip_test.go | 12 +- abxbus-go/tests/event_handler_first_test.go | 124 +++++----- abxbus-go/tests/event_handler_test.go | 81 ++++--- abxbus-go/tests/event_result_test.go | 80 +++---- .../eventbus_cross_runtime_features_test.go | 56 ++--- abxbus-go/tests/eventbus_debounce_test.go | 30 +-- .../eventbus_dispatch_contextvars_test.go | 20 +- .../tests/eventbus_dispatch_defaults_test.go | 12 +- .../eventbus_dispatch_parent_tracking_test.go | 56 ++--- .../tests/eventbus_error_handling_test.go | 20 +- abxbus-go/tests/eventbus_find_test.go | 82 +++---- abxbus-go/tests/eventbus_forwarding_test.go | 98 ++++---- abxbus-go/tests/eventbus_locking_test.go | 48 ++-- abxbus-go/tests/eventbus_log_tree_test.go | 12 +- abxbus-go/tests/eventbus_on_off_test.go | 14 +- abxbus-go/tests/eventbus_performance_test.go | 34 +-- .../tests/eventbus_serialization_test.go | 38 +-- abxbus-go/tests/eventbus_test.go | 190 +++++++-------- abxbus-go/tests/eventbus_timeout_test.go | 106 ++++----- abxbus-go/tests/lock_manager_test.go | 16 +- docs/api/baseevent.mdx | 10 +- docs/api/eventbus.mdx | 23 +- docs/api/eventhandler.mdx | 5 +- docs/concurrency/backpressure.mdx | 2 +- docs/concurrency/events-bus-serial.mdx | 8 +- docs/concurrency/events-global-serial.mdx | 8 +- docs/concurrency/events-parallel.mdx | 6 +- docs/concurrency/handler-completion-all.mdx | 6 +- docs/concurrency/handler-completion-first.mdx | 6 +- docs/concurrency/handlers-parallel.mdx | 6 +- docs/concurrency/handlers-serial.mdx | 6 +- docs/concurrency/immediate-execution.mdx | 26 +-- docs/concurrency/timeouts.mdx | 2 +- docs/features/async-sync-handlers.mdx | 6 +- docs/features/context-propagation.mdx | 6 +- docs/features/event-debouncing.mdx | 8 +- docs/features/event-history-store.mdx | 2 +- docs/features/event-pattern-matching.mdx | 25 +- docs/features/fifo-processing.mdx | 16 +- docs/features/find-events.mdx | 6 +- docs/features/forwarding-between-buses.mdx | 8 +- docs/features/parent-child-tracking.mdx | 24 +- docs/features/return-value-handling.mdx | 27 +-- docs/features/typed-events.mdx | 24 +- docs/further-reading/events-suck.mdx | 12 +- docs/index.mdx | 13 +- docs/quickstart.mdx | 18 +- 52 files changed, 983 insertions(+), 876 deletions(-) diff --git a/abxbus-go/base_event.go b/abxbus-go/base_event.go index a6cfb5eb..dda7bd63 100644 --- a/abxbus-go/base_event.go +++ b/abxbus-go/base_event.go @@ -657,14 +657,6 @@ func (e *BaseEvent) Emit(input any) *BaseEvent { return e.EmitWithContext(nil, input) } -func (e *BaseEvent) EmitEventName(event_name string, payload map[string]any) *BaseEvent { - return e.Emit(NewBaseEvent(event_name, payload)) -} - -func (e *BaseEvent) EmitEventNameWithContext(ctx context.Context, event_name string, payload map[string]any) *BaseEvent { - return e.EmitWithContext(ctx, NewBaseEvent(event_name, payload)) -} - func (e *BaseEvent) EmitWithContext(ctx context.Context, input any) *BaseEvent { event, err := baseEventFromAny(input) if err != nil { diff --git a/abxbus-go/event_bus.go b/abxbus-go/event_bus.go index f9f8ad88..87059aef 100644 --- a/abxbus-go/event_bus.go +++ b/abxbus-go/event_bus.go @@ -298,17 +298,119 @@ func (b *EventBus) notifyBusHandlersChange(handler *EventHandler, registered boo } } -func (b *EventBus) On(event_name string, handler_name string, handler any, options *EventHandler) *EventHandler { +func (b *EventBus) On(args ...any) *EventHandler { + if err := b.rejectIfDestroyed("On"); err != nil { + panic(err) + } + event_name, handler_name, handler, options, err := parseOnArgs(args) + if err != nil { + panic(err) + } if event_name == "" || event_name == "*" { - panic(`EventBus.On registers typed handlers for one concrete event name; use EventBus.OnEventName for wildcard or raw event-name handlers`) + panic(`EventBus.On registers handlers for one concrete event name; use EventBus.OnEventName for wildcard event-name handlers`) } - normalizedHandler, err := normalizeTypedEventHandlerCallable(handler) + normalizedHandler, err := normalizeEventHandlerCallable(handler) if err != nil { panic(err) } return b.registerHandler(event_name, handler_name, normalizedHandler, options) } +func parseOnArgs(args []any) (string, string, any, *EventHandler, error) { + if len(args) == 0 || len(args) > 4 { + return "", "", nil, nil, fmt.Errorf("EventBus.On expects handler, event name + handler, or event name + handler name + handler") + } + handlerName := "handler" + var eventName string + var handler any + var options *EventHandler + if first, ok := args[0].(string); ok { + eventName = first + if len(args) >= 2 { + if second, ok := args[1].(string); ok { + handlerName = second + if len(args) < 3 { + return "", "", nil, nil, fmt.Errorf("EventBus.On missing handler callback") + } + handler = args[2] + if len(args) == 4 { + parsedOptions, err := parseEventHandlerOptions(args[3]) + if err != nil { + return "", "", nil, nil, err + } + options = parsedOptions + } + } else { + if len(args) > 3 { + return "", "", nil, nil, fmt.Errorf("EventBus.On exact-name form expects event name, handler, and optional *EventHandler") + } + handler = args[1] + if len(args) == 3 { + parsedOptions, err := parseEventHandlerOptions(args[2]) + if err != nil { + return "", "", nil, nil, err + } + options = parsedOptions + } + } + } + } else { + if len(args) > 2 { + return "", "", nil, nil, fmt.Errorf("EventBus.On inferred form expects handler and optional *EventHandler") + } + handler = args[0] + inferred, err := inferEventTypeFromHandler(handler) + if err != nil { + return "", "", nil, nil, err + } + eventName = inferred + if len(args) >= 2 { + parsedOptions, err := parseEventHandlerOptions(args[1]) + if err != nil { + return "", "", nil, nil, err + } + options = parsedOptions + } + } + if handler == nil { + return "", "", nil, nil, fmt.Errorf("EventBus.On missing handler callback") + } + return eventName, handlerName, handler, options, nil +} + +func parseEventHandlerOptions(value any) (*EventHandler, error) { + if value == nil { + return nil, nil + } + options, ok := value.(*EventHandler) + if !ok { + return nil, fmt.Errorf("EventBus.On options must be *EventHandler, got %T", value) + } + return options, nil +} + +func inferEventTypeFromHandler(handler any) (string, error) { + value := reflect.ValueOf(handler) + if !value.IsValid() || value.Kind() != reflect.Func || value.IsNil() { + return "", unsupportedHandlerSignatureError(handler) + } + handlerType := value.Type() + if handlerType.NumIn() == 0 { + return "", unsupportedHandlerSignatureError(handler) + } + payloadType := handlerType.In(0) + if payloadType == baseEventPointerType { + return "", fmt.Errorf("EventBus.On cannot infer an event type from *BaseEvent handlers; pass an exact event name or use a typed payload handler") + } + for payloadType.Kind() == reflect.Pointer { + payloadType = payloadType.Elem() + } + if payloadType.Kind() != reflect.Struct || payloadType.Name() == "" { + return "", fmt.Errorf("EventBus.On cannot infer an event type from handler payload %s; pass an exact event name", payloadType) + } + return payloadType.Name(), nil +} + func (b *EventBus) OnEventName(event_pattern string, handler_name string, handler any, options *EventHandler) *EventHandler { if err := b.rejectIfDestroyed("On"); err != nil { panic(err) @@ -421,14 +523,6 @@ func (b *EventBus) Emit(input any) *BaseEvent { return b.EmitWithContext(nil, input) } -func (b *EventBus) EmitEventName(event_name string, payload map[string]any) *BaseEvent { - return b.Emit(NewBaseEvent(event_name, payload)) -} - -func (b *EventBus) EmitEventNameWithContext(ctx context.Context, event_name string, payload map[string]any) *BaseEvent { - return b.EmitWithContext(ctx, NewBaseEvent(event_name, payload)) -} - func (b *EventBus) EmitWithContext(ctx context.Context, input any) *BaseEvent { if err := b.rejectIfDestroyed("Emit"); err != nil { panic(err) diff --git a/abxbus-go/jsonl_bridge.go b/abxbus-go/jsonl_bridge.go index 9387af3e..47492353 100644 --- a/abxbus-go/jsonl_bridge.go +++ b/abxbus-go/jsonl_bridge.go @@ -51,6 +51,11 @@ func (b *JSONLEventBridge) OnEventName(eventPattern string, handlerName string, return b.inboundBus.OnEventName(eventPattern, handlerName, handler, options) } +func (b *JSONLEventBridge) On(eventName string, handlerName string, handler any, options *EventHandler) *EventHandler { + _ = b.Start() + return b.inboundBus.On(eventName, handlerName, handler, options) +} + func (b *JSONLEventBridge) Emit(event *BaseEvent) (*BaseEvent, error) { if err := b.Start(); err != nil { return nil, err @@ -73,10 +78,6 @@ func (b *JSONLEventBridge) Emit(event *BaseEvent) (*BaseEvent, error) { return event, nil } -func (b *JSONLEventBridge) EmitEventName(eventName string, payload map[string]any) (*BaseEvent, error) { - return b.Emit(NewBaseEvent(eventName, payload)) -} - func (b *JSONLEventBridge) Dispatch(event *BaseEvent) (*BaseEvent, error) { return b.Emit(event) } diff --git a/abxbus-go/tests/base_event_test.go b/abxbus-go/tests/base_event_test.go index 8833a407..bb69e700 100644 --- a/abxbus-go/tests/base_event_test.go +++ b/abxbus-go/tests/base_event_test.go @@ -64,10 +64,10 @@ func TestBaseEventNowInsideHandlerNoArgs(t *testing.T) { }) order := []string{} - bus.OnEventName("NowInsideNoArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowInsideNoArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "parent_start") - event.Bus.EmitEventName("NowInsideNoArgsSibling", nil) - child := event.EmitEventName("NowInsideNoArgsChild", nil) + event.Bus.Emit(abxbus.NewBaseEvent("NowInsideNoArgsSibling", nil)) + child := event.Emit(abxbus.NewBaseEvent("NowInsideNoArgsChild", nil)) timeout := 1.0 if _, err := child.Now(&abxbus.EventWaitOptions{Timeout: &timeout}); err != nil { return nil, err @@ -75,16 +75,16 @@ func TestBaseEventNowInsideHandlerNoArgs(t *testing.T) { order = append(order, "parent_end") return nil, nil }, nil) - bus.OnEventName("NowInsideNoArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowInsideNoArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "child") return nil, nil }, nil) - bus.OnEventName("NowInsideNoArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowInsideNoArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "sibling") return nil, nil }, nil) - parent := bus.EmitEventName("NowInsideNoArgsParent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("NowInsideNoArgsParent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -105,26 +105,26 @@ func TestBaseEventNowInsideHandlerWithArgs(t *testing.T) { order := []string{} var child *abxbus.BaseEvent - bus.OnEventName("NowInsideArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowInsideArgsParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "parent_start") - event.Bus.EmitEventName("NowInsideArgsSibling", nil) - child = event.EmitEventName("NowInsideArgsChild", nil) + event.Bus.Emit(abxbus.NewBaseEvent("NowInsideArgsSibling", nil)) + child = event.Emit(abxbus.NewBaseEvent("NowInsideArgsChild", nil)) if _, err := child.Now(); err != nil { return nil, err } order = append(order, "parent_end") return nil, nil }, nil) - bus.OnEventName("NowInsideArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowInsideArgsChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "child") return nil, errors.New("child failure") }, nil) - bus.OnEventName("NowInsideArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowInsideArgsSibling", "sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "sibling") return nil, nil }, nil) - parent := bus.EmitEventName("NowInsideArgsParent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("NowInsideArgsParent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -152,27 +152,27 @@ func TestWaitOutsideHandlerPreservesNormalQueueOrder(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.OnEventName("WaitOutsideHandlerBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("WaitOutsideHandlerBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.OnEventName("WaitOutsideHandlerTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("WaitOutsideHandlerTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return nil, nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.EmitEventName("WaitOutsideHandlerBlockerEvent", nil) + bus.Emit(abxbus.NewBaseEvent("WaitOutsideHandlerBlockerEvent", nil)) select { case <-blockerStarted: case <-ctx.Done(): t.Fatal("blocker did not start") } - target := bus.EmitEventName("WaitOutsideHandlerTargetEvent", nil) + target := bus.Emit(abxbus.NewBaseEvent("WaitOutsideHandlerTargetEvent", nil)) doneCh := make(chan error, 1) go func() { _, err := target.Wait() @@ -204,21 +204,21 @@ func TestNowOutsideHandlerAllowsNormalParallelProcessing(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.OnEventName("NowOutsideHandlerParallelBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowOutsideHandlerParallelBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.OnEventName("NowOutsideHandlerParallelTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowOutsideHandlerParallelTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return nil, nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.EmitEventName("NowOutsideHandlerParallelBlockerEvent", nil) + bus.Emit(abxbus.NewBaseEvent("NowOutsideHandlerParallelBlockerEvent", nil)) select { case <-blockerStarted: case <-ctx.Done(): @@ -258,27 +258,27 @@ func TestWaitReturnsEventWithoutForcingQueuedExecution(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.OnEventName("WaitPassiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("WaitPassiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.OnEventName("WaitPassiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("WaitPassiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return "target", nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.EmitEventName("WaitPassiveBlockerEvent", nil) + bus.Emit(abxbus.NewBaseEvent("WaitPassiveBlockerEvent", nil)) select { case <-blockerStarted: case <-ctx.Done(): t.Fatal("blocker did not start") } - target := bus.EmitEventName("WaitPassiveTargetEvent", nil) + target := bus.Emit(abxbus.NewBaseEvent("WaitPassiveTargetEvent", nil)) waitedEvent := make(chan *abxbus.BaseEvent, 1) waitErr := make(chan error, 1) timeout := 1.0 @@ -312,27 +312,27 @@ func TestNowReturnsEventAndQueueJumpsQueuedExecution(t *testing.T) { blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.OnEventName("NowActiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowActiveBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.OnEventName("NowActiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowActiveTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return "target", nil }, nil) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - bus.EmitEventName("NowActiveBlockerEvent", nil) + bus.Emit(abxbus.NewBaseEvent("NowActiveBlockerEvent", nil)) select { case <-blockerStarted: case <-ctx.Done(): t.Fatal("blocker did not start") } - target := bus.EmitEventName("NowActiveTargetEvent", nil) + target := bus.Emit(abxbus.NewBaseEvent("NowActiveTargetEvent", nil)) processedEvent := make(chan *abxbus.BaseEvent, 1) nowErr := make(chan error, 1) timeout := 1.0 @@ -369,15 +369,15 @@ func TestWaitFirstResultReturnsBeforeEventCompletion(t *testing.T) { EventTimeout: &noTimeout, }) slowFinished := make(chan struct{}) - bus.OnEventName("WaitFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("WaitFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "medium", nil }, nil) - bus.OnEventName("WaitFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("WaitFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.OnEventName("WaitFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("WaitFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(250 * time.Millisecond) close(slowFinished) return "slow", nil @@ -428,11 +428,11 @@ func TestNowFirstResultReturnsBeforeEventCompletion(t *testing.T) { slowFinished := make(chan struct{}) slowCanceled := make(chan struct{}) releaseSlow := make(chan struct{}) - bus.OnEventName("NowFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowFirstResultEvent", "medium", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "medium", nil }, nil) - bus.OnEventName("NowFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowFirstResultEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-slowStarted: case <-time.After(time.Second): @@ -441,7 +441,7 @@ func TestNowFirstResultReturnsBeforeEventCompletion(t *testing.T) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.OnEventName("NowFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowFirstResultEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { close(slowStarted) select { case <-releaseSlow: @@ -499,21 +499,21 @@ func TestEventResultStartsNeverStartedEventAndReturnsFirstResult(t *testing.T) { order := []string{} blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.OnEventName("EventResultShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.OnEventName("EventResultShortcutTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultShortcutTargetEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "target") return "target", nil }, nil) - bus.EmitEventName("EventResultShortcutBlockerEvent", nil) + bus.Emit(abxbus.NewBaseEvent("EventResultShortcutBlockerEvent", nil)) <-blockerStarted - target := bus.EmitEventName("EventResultShortcutTargetEvent", nil) + target := bus.Emit(abxbus.NewBaseEvent("EventResultShortcutTargetEvent", nil)) resultCh := make(chan any, 1) errCh := make(chan error, 1) go func() { @@ -542,25 +542,25 @@ func TestEventResultsListStartsNeverStartedEventAndReturnsAllResults(t *testing. order := []string{} blockerStarted := make(chan struct{}) releaseBlocker := make(chan struct{}) - bus.OnEventName("EventResultsShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultsShortcutBlockerEvent", "blocker", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "blocker_start") close(blockerStarted) <-releaseBlocker order = append(order, "blocker_end") return nil, nil }, nil) - bus.OnEventName("EventResultsShortcutTargetEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultsShortcutTargetEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "first") return "first", nil }, nil) - bus.OnEventName("EventResultsShortcutTargetEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultsShortcutTargetEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { order = append(order, "second") return "second", nil }, nil) - bus.EmitEventName("EventResultsShortcutBlockerEvent", nil) + bus.Emit(abxbus.NewBaseEvent("EventResultsShortcutBlockerEvent", nil)) <-blockerStarted - target := bus.EmitEventName("EventResultsShortcutTargetEvent", nil) + target := bus.Emit(abxbus.NewBaseEvent("EventResultsShortcutTargetEvent", nil)) resultsCh := make(chan []any, 1) errCh := make(chan error, 1) go func() { @@ -601,13 +601,13 @@ func TestEventResultHelpersDoNotWaitForStartedEvent(t *testing.T) { }) handlerStarted := make(chan struct{}) releaseHandler := make(chan struct{}) - bus.OnEventName("EventResultHelpersStartedEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultHelpersStartedEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { close(handlerStarted) <-releaseHandler return "late", nil }, nil) - event := bus.EmitEventName("EventResultHelpersStartedEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("EventResultHelpersStartedEvent", nil)) <-handlerStarted if event.EventStatus != "started" { @@ -669,14 +669,14 @@ func TestNowOnAlreadyExecutingEventWaitsWithoutDuplicateExecution(t *testing.T) started := make(chan struct{}) release := make(chan struct{}) runCount := 0 - bus.OnEventName("NowAlreadyExecutingEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowAlreadyExecutingEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { runCount++ close(started) <-release return "done", nil }, nil) - event := bus.EmitEventName("NowAlreadyExecutingEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("NowAlreadyExecutingEvent", nil)) <-started nowCh := make(chan *abxbus.BaseEvent, 1) errCh := make(chan error, 1) @@ -717,7 +717,7 @@ func TestNowTimeoutLimitsCallerWaitAndBackgroundProcessingContinues(t *testing.T handlerSawContextCancel := make(chan struct{}, 1) var startOnce sync.Once - bus.OnEventName("NowTimeoutCallerWaitEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowTimeoutCallerWaitEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { startOnce.Do(func() { close(started) }) select { case <-ctx.Done(): @@ -729,7 +729,7 @@ func TestNowTimeoutLimitsCallerWaitAndBackgroundProcessingContinues(t *testing.T } }, nil) - event := bus.EmitEventName("NowTimeoutCallerWaitEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("NowTimeoutCallerWaitEvent", nil)) timeout := 0.01 if _, err := event.Now(&abxbus.EventWaitOptions{Timeout: &timeout}); err == nil { t.Fatal("expected Now(timeout) to time out") @@ -779,12 +779,12 @@ func TestNowWithRapidHandlerChurnDoesNotDuplicateExecution(t *testing.T) { var runCount atomic.Int64 for index := 0; index < totalEvents; index++ { - handler := bus.OnEventName("NowRapidHandlerChurnEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.On("NowRapidHandlerChurnEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { runCount.Add(1) time.Sleep(time.Millisecond) return "done", nil }, nil) - event := bus.EmitEventName("NowRapidHandlerChurnEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("NowRapidHandlerChurnEvent", nil)) timeout := 1.0 completed, err := event.Now(&abxbus.EventWaitOptions{Timeout: &timeout}) if err != nil { @@ -812,20 +812,20 @@ func TestEventResultOptionsApplyToCurrentResults(t *testing.T) { EventTimeout: &noTimeout, }) releaseSlow := make(chan struct{}) - bus.OnEventName("EventResultOptionsCurrentResultsEvent", "fail", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultOptionsCurrentResultsEvent", "fail", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("option boom") }, nil) - bus.OnEventName("EventResultOptionsCurrentResultsEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultOptionsCurrentResultsEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "keep", nil }, nil) - bus.OnEventName("EventResultOptionsCurrentResultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventResultOptionsCurrentResultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-releaseSlow return "late", nil }, nil) timeout := 1.0 - event, err := bus.EmitEventName("EventResultOptionsCurrentResultsEvent", nil).Now( + event, err := bus.Emit(abxbus.NewBaseEvent("EventResultOptionsCurrentResultsEvent", nil)).Now( &abxbus.EventWaitOptions{Timeout: &timeout, FirstResult: true}, ) if err != nil { @@ -853,11 +853,11 @@ func TestEventResultOptionsApplyToCurrentResults(t *testing.T) { func TestBaseEventNowOutsideHandlerNoArgs(t *testing.T) { bus := abxbus.NewEventBus("BaseEventNowOutsideNoArgsBus", nil) - bus.OnEventName("NowOutsideNoArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowOutsideNoArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("outside failure") }, nil) - event := bus.EmitEventName("NowOutsideNoArgsEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("NowOutsideNoArgsEvent", nil)) timeout := 1.0 if _, err := event.Now(&abxbus.EventWaitOptions{Timeout: &timeout}); err != nil { t.Fatalf("Now should wait without surfacing handler errors, got %v", err) @@ -872,11 +872,11 @@ func TestBaseEventNowOutsideHandlerNoArgs(t *testing.T) { func TestBaseEventNowOutsideHandlerWithArgs(t *testing.T) { bus := abxbus.NewEventBus("BaseEventNowOutsideArgsBus", nil) - bus.OnEventName("NowOutsideArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowOutsideArgsEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("outside suppressed failure") }, nil) - event := bus.EmitEventName("NowOutsideArgsEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("NowOutsideArgsEvent", nil)) if _, err := event.Now(); err != nil { t.Fatalf("RaiseIfAny=false should only wait for completion, got %v", err) } @@ -910,7 +910,7 @@ func TestBaseEventEventResultUpdateCreatesAndUpdatesTypedHandlerResults(t *testi bus := abxbus.NewEventBus("BaseEventEventResultUpdateBus", nil) event := abxbus.NewBaseEvent("BaseEventEventResultUpdateEvent", nil) event.EventResultType = map[string]any{"type": "string"} - handlerEntry := bus.OnEventName("BaseEventEventResultUpdateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerEntry := bus.On("BaseEventEventResultUpdateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -949,7 +949,7 @@ func TestBaseEventEventResultUpdateStatusOnlyPreservesExistingErrorAndResult(t * bus := abxbus.NewEventBus("BaseEventEventResultUpdateStatusOnlyBus", nil) event := abxbus.NewBaseEvent("BaseEventEventResultUpdateStatusOnlyEvent", nil) event.EventResultType = map[string]any{"type": "string"} - handlerEntry := bus.OnEventName("BaseEventEventResultUpdateStatusOnlyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerEntry := bus.On("BaseEventEventResultUpdateStatusOnlyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -984,7 +984,7 @@ func TestBaseEventEventResultUpdateValidatesDeclaredResultSchema(t *testing.T) { bus := abxbus.NewEventBus("BaseEventEventResultUpdateSchemaBus", nil) event := abxbus.NewBaseEvent("BaseEventEventResultUpdateSchemaEvent", nil) event.EventResultType = map[string]any{"type": "string"} - handlerEntry := bus.OnEventName("BaseEventEventResultUpdateSchemaEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerEntry := bus.On("BaseEventEventResultUpdateSchemaEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -1019,28 +1019,28 @@ func TestWaitWaitsInQueueOrderInsideHandler(t *testing.T) { orderCh <- label } - bus.OnEventName("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - bus.EmitEventName("Sibling", nil) + bus.Emit(abxbus.NewBaseEvent("Sibling", nil)) select { case <-siblingStarted: case <-time.After(time.Second): return nil, errors.New("timed out waiting for sibling to start") } - child = e.EmitEventName("Child", nil) + child = e.Emit(abxbus.NewBaseEvent("Child", nil)) if _, err := child.Wait(); err != nil { return nil, err } record("parent_end") return "parent", nil }, nil) - bus.OnEventName("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") time.Sleep(time.Millisecond) record("child_end") return "child", nil }, nil) - bus.OnEventName("Sibling", "sibling", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Sibling", "sibling", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("sibling_start") siblingStarted <- struct{}{} time.Sleep(time.Millisecond) @@ -1048,7 +1048,7 @@ func TestWaitWaitsInQueueOrderInsideHandler(t *testing.T) { return "sibling", nil }, nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1092,10 +1092,10 @@ func TestWaitIsPassiveInsideHandlersAndTimesOutForSerialEvents(t *testing.T) { return append([]string{}, order...) } - bus.OnEventName("PassiveSerialParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PassiveSerialParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - emitted := e.EmitEventName("PassiveSerialEmittedEvent", nil) - foundSource := e.EmitEventName("PassiveSerialFoundEvent", nil) + emitted := e.Emit(abxbus.NewBaseEvent("PassiveSerialEmittedEvent", nil)) + foundSource := e.Emit(abxbus.NewBaseEvent("PassiveSerialFoundEvent", nil)) found, err := bus.FindEventName("PassiveSerialFoundEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { return nil, err @@ -1123,16 +1123,16 @@ func TestWaitIsPassiveInsideHandlersAndTimesOutForSerialEvents(t *testing.T) { record("parent_end") return "parent", nil }, nil) - bus.OnEventName("PassiveSerialEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PassiveSerialEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("emitted_start") return "emitted", nil }, nil) - bus.OnEventName("PassiveSerialFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PassiveSerialFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("found_start") return "found", nil }, nil) - if _, err := bus.EmitEventName("PassiveSerialParentEvent", nil).Now(); err != nil { + if _, err := bus.Emit(abxbus.NewBaseEvent("PassiveSerialParentEvent", nil)).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 @@ -1176,9 +1176,9 @@ func TestWaitSerialWaitInsideHandlerTimesOutAndWarnsAboutSlowHandler(t *testing. } defer func() { abxbus.SlowWarningLogger = original }() - bus.OnEventName("EventCompletedSerialDeadlockWarningParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventCompletedSerialDeadlockWarningParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - child := e.EmitEventName("EventCompletedSerialDeadlockWarningChildEvent", nil) + child := e.Emit(abxbus.NewBaseEvent("EventCompletedSerialDeadlockWarningChildEvent", nil)) found, err := bus.FindEventName("EventCompletedSerialDeadlockWarningChildEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) if err != nil { return nil, err @@ -1200,12 +1200,12 @@ func TestWaitSerialWaitInsideHandlerTimesOutAndWarnsAboutSlowHandler(t *testing. record("parent_end") return "parent", nil }, nil) - bus.OnEventName("EventCompletedSerialDeadlockWarningChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventCompletedSerialDeadlockWarningChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") return "child", nil }, nil) - if _, err := bus.EmitEventName("EventCompletedSerialDeadlockWarningParentEvent", nil).Now(); err != nil { + if _, err := bus.Emit(abxbus.NewBaseEvent("EventCompletedSerialDeadlockWarningParentEvent", nil)).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 @@ -1241,23 +1241,23 @@ func TestDeferredEmitAfterHandlerCompletionIsAccepted(t *testing.T) { } emitted := make(chan struct{}) - bus.OnEventName("DeferredEmitAfterCompletionParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("DeferredEmitAfterCompletionParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") go func() { time.Sleep(20 * time.Millisecond) record("deferred_emit") - e.EmitEventName("DeferredEmitAfterCompletionChildEvent", nil) + e.Emit(abxbus.NewBaseEvent("DeferredEmitAfterCompletionChildEvent", nil)) close(emitted) }() record("parent_end") return "parent", nil }, nil) - bus.OnEventName("DeferredEmitAfterCompletionChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("DeferredEmitAfterCompletionChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") return "child", nil }, nil) - if _, err := bus.EmitEventName("DeferredEmitAfterCompletionParentEvent", nil).Now(); err != nil { + if _, err := bus.Emit(abxbus.NewBaseEvent("DeferredEmitAfterCompletionParentEvent", nil)).Now(); err != nil { t.Fatal(err) } select { @@ -1293,7 +1293,7 @@ func TestWaitWaitsForNormalParallelProcessingInsideHandlers(t *testing.T) { return append([]string{}, order...) } - bus.OnEventName("PassiveParallelParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PassiveParallelParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") emittedEvent := abxbus.NewBaseEvent("PassiveParallelEmittedEvent", nil) emittedEvent.EventConcurrency = abxbus.EventConcurrencyParallel @@ -1324,20 +1324,20 @@ func TestWaitWaitsForNormalParallelProcessingInsideHandlers(t *testing.T) { record("parent_end") return "parent", nil }, nil) - bus.OnEventName("PassiveParallelEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PassiveParallelEmittedEvent", "emitted", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("emitted_start") time.Sleep(time.Millisecond) record("emitted_end") return "emitted", nil }, nil) - bus.OnEventName("PassiveParallelFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PassiveParallelFoundEvent", "found", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("found_start") time.Sleep(time.Millisecond) record("found_end") return "found", nil }, nil) - if _, err := bus.EmitEventName("PassiveParallelParentEvent", nil).Now(); err != nil { + if _, err := bus.Emit(abxbus.NewBaseEvent("PassiveParallelParentEvent", nil)).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 @@ -1370,7 +1370,7 @@ func TestAwaitedParallelQueueJumpChildDoesNotPauseLaterParallelChildEvents(t *te return child } - bus.OnEventName("ParallelPauseParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ParallelPauseParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "parent_start") if _, err := e.Emit(newChild("awaited")).Now(&abxbus.EventWaitOptions{FirstResult: true}); err != nil { return nil, err @@ -1393,21 +1393,21 @@ func TestAwaitedParallelQueueJumpChildDoesNotPauseLaterParallelChildEvents(t *te return nil, nil }, nil) - bus.OnEventName("ParallelPauseChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ParallelPauseChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { name, _ := e.Payload["name"].(string) appendLocked(&mu, &order, "child_start_"+name) if name == "bg" { - e.EmitEventName("ParallelPauseObservedEvent", map[string]any{"name": "bg"}) + e.Emit(abxbus.NewBaseEvent("ParallelPauseObservedEvent", map[string]any{"name": "bg"})) } appendLocked(&mu, &order, "child_end_"+name) return name, nil }, nil) - bus.OnEventName("ParallelPauseObservedEvent", "observed_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ParallelPauseObservedEvent", "observed_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "observed_seen") return nil, nil }, nil) - parent := bus.EmitEventName("ParallelPauseParentEvent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("ParallelPauseParentEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1428,12 +1428,12 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { order := []string{} parallelDone := make(chan struct{}) - bus.OnEventName("ParallelNotPausedParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ParallelNotPausedParentEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "parent_start") parallelEvent := abxbus.NewBaseEvent("ParallelNotPausedParallelEvent", nil) parallelEvent.EventConcurrency = abxbus.EventConcurrencyParallel e.Emit(parallelEvent) - child := e.EmitEventName("ParallelNotPausedChildEvent", nil) + child := e.Emit(abxbus.NewBaseEvent("ParallelNotPausedChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } @@ -1441,7 +1441,7 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { return nil, nil }, nil) - bus.OnEventName("ParallelNotPausedParallelEvent", "parallel_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ParallelNotPausedParallelEvent", "parallel_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "parallel_start") time.Sleep(5 * time.Millisecond) appendLocked(&mu, &order, "parallel_end") @@ -1449,7 +1449,7 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { return nil, nil }, nil) - bus.OnEventName("ParallelNotPausedChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ParallelNotPausedChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "child_start") select { case <-parallelDone: @@ -1461,7 +1461,7 @@ func TestSerialQueueJumpChildDoesNotPauseExistingParallelEvent(t *testing.T) { return nil, nil }, nil) - parent := bus.EmitEventName("ParallelNotPausedParentEvent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("ParallelNotPausedParentEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1489,7 +1489,7 @@ func TestWaitWaitsForFutureParallelEventFoundAfterHandlerStarts(t *testing.T) { continued := make(chan struct{}) waitedFor := make(chan time.Duration, 1) - bus.OnEventName("FutureParallelSomeOtherEvent", "other", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("FutureParallelSomeOtherEvent", "other", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { close(otherStarted) <-releaseFind found, err := bus.FindEventName("FutureParallelEvent", nil, &abxbus.FindOptions{Past: true, Future: false}) @@ -1508,13 +1508,13 @@ func TestWaitWaitsForFutureParallelEventFoundAfterHandlerStarts(t *testing.T) { close(continued) return "other", nil }, nil) - bus.OnEventName("FutureParallelEvent", "parallel", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("FutureParallelEvent", "parallel", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { close(parallelStarted) time.Sleep(250 * time.Millisecond) return "parallel", nil }, nil) - other := bus.EmitEventName("FutureParallelSomeOtherEvent", nil) + other := bus.Emit(abxbus.NewBaseEvent("FutureParallelSomeOtherEvent", nil)) select { case <-otherStarted: case <-time.After(time.Second): @@ -1564,11 +1564,11 @@ func TestWaitReturnsEventAcceptsTimeoutAndRejectsUnattachedPendingEvent(t *testi EventConcurrency: abxbus.EventConcurrencyBusSerial, }) releaseHandler := make(chan struct{}) - bus.OnEventName("EventCompletedTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventCompletedTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-releaseHandler return nil, nil }, nil) - event := bus.EmitEventName("EventCompletedTimeoutEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("EventCompletedTimeoutEvent", nil)) if _, err := event.Wait(&abxbus.EventWaitOptions{Timeout: &timeout}); err == nil || !strings.Contains(err.Error(), "deadline") { t.Fatalf("Wait should time out, got %v", err) } @@ -1601,12 +1601,12 @@ func baseEventContainsString(values []string, needle string) bool { func TestBaseEventCarriesEventBusReferenceDuringDispatch(t *testing.T) { bus := abxbus.NewEventBus("ProxyBus", nil) var seenBus *abxbus.EventBus - bus.OnEventName("ProxyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ProxyEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenBus = event.Bus return event.Bus.Name, nil }, nil) - event := bus.EmitEventName("ProxyEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("ProxyEvent", nil)) result, err := event.EventResult() if err != nil { t.Fatal(err) @@ -1625,12 +1625,12 @@ func TestBaseEventBusReferenceReflectsForwardedProcessingBus(t *testing.T) { }, nil) var targetSeenBus *abxbus.EventBus - target.OnEventName("ProxyForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + target.On("ProxyForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { targetSeenBus = event.Bus return event.Bus.Name, nil }, nil) - event := source.EmitEventName("ProxyForwardEvent", nil) + event := source.Emit(abxbus.NewBaseEvent("ProxyForwardEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1660,22 +1660,22 @@ func TestEventEmitFromForwardedHandlerDispatchesChildOnTargetBus(t *testing.T) { var child *abxbus.BaseEvent var childSeenBus *abxbus.EventBus - targetHandler := target.OnEventName("ProxyParentEvent", "target_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + targetHandler := target.On("ProxyParentEvent", "target_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if event.Bus != target { t.Fatalf("target parent handler should see target bus, got %p want %p", event.Bus, target) } - child = event.EmitEventName("ProxyChildEvent", nil) + child = event.Emit(abxbus.NewBaseEvent("ProxyChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } return "parent", nil }, nil) - target.OnEventName("ProxyChildEvent", "target_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + target.On("ProxyChildEvent", "target_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childSeenBus = event.Bus return "child", nil }, nil) - parent := source.EmitEventName("ProxyParentEvent", nil) + parent := source.Emit(abxbus.NewBaseEvent("ProxyParentEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1713,7 +1713,7 @@ func mustJSON(t *testing.T, event *abxbus.BaseEvent) []byte { func TestBaseEventRuntimeStateTransitionsAndJSON(t *testing.T) { bus := abxbus.NewEventBus("RuntimeStateBus", nil) - bus.OnEventName("RuntimeStateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("RuntimeStateEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if event.EventStatus != "started" { t.Fatalf("handler should see started status, got %s", event.EventStatus) } diff --git a/abxbus-go/tests/comprehensive_patterns_test.go b/abxbus-go/tests/comprehensive_patterns_test.go index 6fa34a7d..be8a41c9 100644 --- a/abxbus-go/tests/comprehensive_patterns_test.go +++ b/abxbus-go/tests/comprehensive_patterns_test.go @@ -96,15 +96,15 @@ func TestComprehensivePatternsForwardingDispatchAndParentTracking(t *testing.T) var asyncChild *abxbus.BaseEvent var syncChild *abxbus.BaseEvent - bus1.OnEventName("ParentEvent", "parent_bus1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.On("ParentEvent", "parent_bus1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { next("parent_start") - asyncChild = e.EmitEventName("QueuedChildEvent", nil) + asyncChild = e.Emit(abxbus.NewBaseEvent("QueuedChildEvent", nil)) if asyncChild.EventStatus == "completed" { t.Fatalf("unawaited child should not be completed inside parent handler") } - syncChild = e.EmitEventName("ImmediateChildEvent", nil) + syncChild = e.Emit(abxbus.NewBaseEvent("ImmediateChildEvent", nil)) if _, err := syncChild.Now(); err != nil { return nil, err } @@ -122,7 +122,7 @@ func TestComprehensivePatternsForwardingDispatchAndParentTracking(t *testing.T) return "parent_done", nil }, nil) - parent := bus1.EmitEventName("ParentEvent", nil) + parent := bus1.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -184,7 +184,7 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { bus := bus for _, pattern := range []string{"QueuedChildEvent", "ImmediateChildEvent"} { pattern := pattern - bus.OnEventName(pattern, pattern+"_child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On(pattern, pattern+"_child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &results, "child_"+bus.Label()) time.Sleep(time.Millisecond) return "child_done_" + bus.Label(), nil @@ -192,13 +192,13 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { } } - bus1.OnEventName("RootEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.On("RootEvent", "parent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { children := []*abxbus.BaseEvent{} for i := 0; i < 3; i++ { - children = append(children, e.EmitEventName("QueuedChildEvent", nil)) + children = append(children, e.Emit(abxbus.NewBaseEvent("QueuedChildEvent", nil))) } for i := 0; i < 3; i++ { - child := e.EmitEventName("ImmediateChildEvent", nil) + child := e.Emit(abxbus.NewBaseEvent("ImmediateChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } @@ -214,7 +214,7 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { } return "parent_done", nil }, nil) - bus1.OnEventName("RootEvent", "bad_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.On("RootEvent", "bad_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) @@ -223,7 +223,7 @@ func TestComprehensiveRaceConditionStress(t *testing.T) { results = []string{} mu.Unlock() - event := bus1.EmitEventName("RootEvent", nil) + event := bus1.Emit(abxbus.NewBaseEvent("RootEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -245,9 +245,9 @@ func TestComprehensiveAwaitedChildJumpsQueueWithoutOvershoot(t *testing.T) { var mu sync.Mutex order := []string{} - bus.OnEventName("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event1_start") - child := e.EmitEventName("ChildEvent", nil) + child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) appendLocked(&mu, &order, "Child_dispatched") if _, err := child.Now(); err != nil { return nil, err @@ -256,25 +256,25 @@ func TestComprehensiveAwaitedChildJumpsQueueWithoutOvershoot(t *testing.T) { appendLocked(&mu, &order, "Event1_end") return "event1_done", nil }, nil) - bus.OnEventName("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event2_start") appendLocked(&mu, &order, "Event2_end") return "event2_done", nil }, nil) - bus.OnEventName("Event3", "event3_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Event3", "event3_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event3_start") appendLocked(&mu, &order, "Event3_end") return "event3_done", nil }, nil) - bus.OnEventName("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Child_start") appendLocked(&mu, &order, "Child_end") return "child_done", nil }, nil) - event1 := bus.EmitEventName("Event1", nil) - event2 := bus.EmitEventName("Event2", nil) - event3 := bus.EmitEventName("Event3", nil) + event1 := bus.Emit(abxbus.NewBaseEvent("Event1", nil)) + event2 := bus.Emit(abxbus.NewBaseEvent("Event2", nil)) + event3 := bus.Emit(abxbus.NewBaseEvent("Event3", nil)) if _, err := event1.Now(); err != nil { t.Fatal(err) @@ -306,13 +306,13 @@ func TestComprehensiveDispatchMultipleAwaitOneSkipsOthersUntilAfterHandler(t *te var mu sync.Mutex order := []string{} - bus.OnEventName("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Event1_start") - e.EmitEventName("ChildA", nil) + e.Emit(abxbus.NewBaseEvent("ChildA", nil)) appendLocked(&mu, &order, "ChildA_dispatched") - childB := e.EmitEventName("ChildB", nil) + childB := e.Emit(abxbus.NewBaseEvent("ChildB", nil)) appendLocked(&mu, &order, "ChildB_dispatched") - e.EmitEventName("ChildC", nil) + e.Emit(abxbus.NewBaseEvent("ChildC", nil)) appendLocked(&mu, &order, "ChildC_dispatched") if _, err := childB.Now(); err != nil { return nil, err @@ -323,16 +323,16 @@ func TestComprehensiveDispatchMultipleAwaitOneSkipsOthersUntilAfterHandler(t *te }, nil) for _, eventType := range []string{"Event2", "Event3", "ChildA", "ChildB", "ChildC"} { eventType := eventType - bus.OnEventName(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, eventType+"_start") appendLocked(&mu, &order, eventType+"_end") return strings.ToLower(eventType) + "_done", nil }, nil) } - event1 := bus.EmitEventName("Event1", nil) - bus.EmitEventName("Event2", nil) - bus.EmitEventName("Event3", nil) + event1 := bus.Emit(abxbus.NewBaseEvent("Event1", nil)) + bus.Emit(abxbus.NewBaseEvent("Event2", nil)) + bus.Emit(abxbus.NewBaseEvent("Event3", nil)) if _, err := event1.Now(); err != nil { t.Fatal(err) @@ -365,9 +365,9 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { bus2Started := make(chan struct{}) closeBus2Started := sync.Once{} - bus1.OnEventName("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.On("Event1", "event1_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Bus1_Event1_start") - child := e.EmitEventName("ChildEvent", nil) + child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) appendLocked(&mu, &order, "Child_dispatched_to_Bus1") if _, err := child.Now(); err != nil { return nil, err @@ -376,12 +376,12 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { appendLocked(&mu, &order, "Bus1_Event1_end") return "event1_done", nil }, nil) - bus1.OnEventName("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.On("Event2", "event2_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Bus1_Event2_start") appendLocked(&mu, &order, "Bus1_Event2_end") return "event2_done", nil }, nil) - bus1.OnEventName("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus1.On("ChildEvent", "child_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Child_start") select { case <-bus2Started: @@ -393,7 +393,7 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { }, nil) for _, eventType := range []string{"Event3", "Event4"} { eventType := eventType - bus2.OnEventName(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus2.On(eventType, eventType+"_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLocked(&mu, &order, "Bus2_"+eventType+"_start") if eventType == "Event3" { closeBus2Started.Do(func() { close(bus2Started) }) @@ -403,10 +403,10 @@ func TestComprehensiveMultiBusQueuesIndependentWhenAwaitingChild(t *testing.T) { }, nil) } - event1 := bus1.EmitEventName("Event1", nil) - bus1.EmitEventName("Event2", nil) - bus2.EmitEventName("Event3", nil) - bus2.EmitEventName("Event4", nil) + event1 := bus1.Emit(abxbus.NewBaseEvent("Event1", nil)) + bus1.Emit(abxbus.NewBaseEvent("Event2", nil)) + bus2.Emit(abxbus.NewBaseEvent("Event3", nil)) + bus2.Emit(abxbus.NewBaseEvent("Event4", nil)) waitForEntry(t, &mu, &order, "Bus2_Event3_start") if _, err := event1.Now(); err != nil { diff --git a/abxbus-go/tests/cross_runtime_roundtrip_test.go b/abxbus-go/tests/cross_runtime_roundtrip_test.go index e6cccc87..4a714243 100644 --- a/abxbus-go/tests/cross_runtime_roundtrip_test.go +++ b/abxbus-go/tests/cross_runtime_roundtrip_test.go @@ -360,7 +360,7 @@ func assertGoHandlerResultAccepted(t *testing.T, eventPayload map[string]any, re isolateSchemaAssertionEvent(event) bus := abxbus.NewEventBus("GoRoundtripSchemaAccepted", nil) defer bus.Destroy() - bus.OnEventName(event.EventType, "valid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On(event.EventType, "valid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return result, nil }, nil) executed, err := bus.Emit(event).Now(&abxbus.EventWaitOptions{FirstResult: true}) @@ -379,7 +379,7 @@ func assertGoHandlerResultRejected(t *testing.T, eventPayload map[string]any, re isolateSchemaAssertionEvent(event) bus := abxbus.NewEventBus("GoRoundtripSchemaRejected", nil) defer bus.Destroy() - bus.OnEventName(event.EventType, "invalid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On(event.EventType, "invalid", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return result, nil }, nil) executed, err := bus.Emit(event).Now(&abxbus.EventWaitOptions{FirstResult: true}) @@ -557,7 +557,7 @@ func TestJSONLEventBridgeForwardsEventsThroughFile(t *testing.T) { defer reader.Close() received := make(chan *abxbus.BaseEvent, 1) - reader.OnEventName("JSONLTestEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + reader.On("JSONLTestEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { received <- event return "ok", nil }, nil) @@ -593,7 +593,7 @@ func TestJSONLEventBridgeIgnoresMalformedLinesAndKeepsPolling(t *testing.T) { defer reader.Close() received := make(chan *abxbus.BaseEvent, 1) - reader.OnEventName("ValidEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + reader.On("ValidEvent", "capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { received <- event return nil, nil }, nil) @@ -603,7 +603,7 @@ func TestJSONLEventBridgeIgnoresMalformedLinesAndKeepsPolling(t *testing.T) { } writer := abxbus.NewJSONLEventBridge(path, 0.01, "JSONLWriterMalformed") defer writer.Close() - if _, err := writer.EmitEventName("ValidEvent", map[string]any{"ok": true}); err != nil { + if _, err := writer.Emit(abxbus.NewBaseEvent("ValidEvent", map[string]any{"ok": true})); err != nil { t.Fatal(err) } @@ -690,7 +690,7 @@ func measureJSONLBridgeWarmLatencyMS(t *testing.T, jsonlPath string) float64 { measuredCount := 0 warmupOnce := sync.Once{} measuredOnce := sync.Once{} - receiver.OnEventName("IPCPingEvent", "latency_capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + receiver.On("IPCPingEvent", "latency_capture", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { label, _ := event.Payload["label"].(string) countsMu.Lock() defer countsMu.Unlock() diff --git a/abxbus-go/tests/event_handler_first_test.go b/abxbus-go/tests/event_handler_first_test.go index 0f268dde..03c636c4 100644 --- a/abxbus-go/tests/event_handler_first_test.go +++ b/abxbus-go/tests/event_handler_first_test.go @@ -18,15 +18,15 @@ func TestEventHandlerCompletionBusDefaultFirstSerial(t *testing.T) { }) secondHandlerCalled := false - bus.OnEventName("CompletionDefaultFirstEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionDefaultFirstEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.OnEventName("CompletionDefaultFirstEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionDefaultFirstEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondHandlerCalled = true return "second", nil }, nil) - event := bus.EmitEventName("CompletionDefaultFirstEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("CompletionDefaultFirstEvent", nil)) if event.EventHandlerCompletion != "" { t.Fatalf("event_handler_completion should be unset on the event, got %s", event.EventHandlerCompletion) } @@ -58,10 +58,10 @@ func TestEventHandlerCompletionExplicitOverrideBeatsBusDefault(t *testing.T) { }) secondHandlerCalled := false - bus.OnEventName("CompletionOverrideEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionOverrideEvent", "first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.OnEventName("CompletionOverrideEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionOverrideEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondHandlerCalled = true return "second", nil }, nil) @@ -87,7 +87,7 @@ func TestEventParallelFirstRacesAndCancelsNonWinners(t *testing.T) { }) var slowStarted atomic.Bool - bus.OnEventName("CompletionParallelFirstEvent", "slow_handler_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionParallelFirstEvent", "slow_handler_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { slowStarted.Store(true) select { case <-time.After(500 * time.Millisecond): @@ -96,11 +96,11 @@ func TestEventParallelFirstRacesAndCancelsNonWinners(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.OnEventName("CompletionParallelFirstEvent", "fast_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionParallelFirstEvent", "fast_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "winner", nil }, nil) - bus.OnEventName("CompletionParallelFirstEvent", "slow_handler_pending_or_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionParallelFirstEvent", "slow_handler_pending_or_started", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(500 * time.Millisecond): return "slow-other", nil @@ -154,11 +154,11 @@ func TestEventHandlerCompletionExplicitFirstCancelsParallelLosers(t *testing.T) }) var slowHandlerCompleted atomic.Bool - bus.OnEventName("CompletionFirstShortcutEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstShortcutEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.OnEventName("CompletionFirstShortcutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstShortcutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(500 * time.Millisecond): slowHandlerCompleted.Store(true) @@ -200,10 +200,10 @@ func TestEventHandlerCompletionFirstPreservesFalsyResults(t *testing.T) { }) secondHandlerCalled := false - bus.OnEventName("IntCompletionEvent", "zero_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("IntCompletionEvent", "zero_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return 0, nil }, nil) - bus.OnEventName("IntCompletionEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("IntCompletionEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondHandlerCalled = true return 99, nil }, nil) @@ -229,10 +229,10 @@ func TestEventHandlerCompletionFirstPreservesFalseAndEmptyStringResults(t *testi EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) boolSecondHandlerCalled := false - boolBus.OnEventName("BoolCompletionEvent", "bool_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + boolBus.On("BoolCompletionEvent", "bool_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return false, nil }, nil) - boolBus.OnEventName("BoolCompletionEvent", "bool_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + boolBus.On("BoolCompletionEvent", "bool_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { boolSecondHandlerCalled = true return true, nil }, nil) @@ -256,10 +256,10 @@ func TestEventHandlerCompletionFirstPreservesFalseAndEmptyStringResults(t *testi EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) strSecondHandlerCalled := false - strBus.OnEventName("StrCompletionEvent", "str_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + strBus.On("StrCompletionEvent", "str_first_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "", nil }, nil) - strBus.OnEventName("StrCompletionEvent", "str_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + strBus.On("StrCompletionEvent", "str_second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { strSecondHandlerCalled = true return "second", nil }, nil) @@ -285,13 +285,13 @@ func TestEventHandlerCompletionFirstSkipsNoneResultAndUsesNextWinner(t *testing. EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) thirdHandlerCalled := false - bus.OnEventName("CompletionNoneSkipEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNoneSkipEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.OnEventName("CompletionNoneSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNoneSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - bus.OnEventName("CompletionNoneSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNoneSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { thirdHandlerCalled = true return "third", nil }, nil) @@ -325,13 +325,13 @@ func TestEventHandlerCompletionFirstSkipsBaseEventResultAndUsesNextWinner(t *tes EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) thirdHandlerCalled := false - bus.OnEventName("CompletionBaseEventSkipEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionBaseEventSkipEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return abxbus.NewBaseEvent("ChildCompletionEvent", nil), nil }, nil) - bus.OnEventName("CompletionBaseEventSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionBaseEventSkipEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - bus.OnEventName("CompletionBaseEventSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionBaseEventSkipEvent", "third_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { thirdHandlerCalled = true return "third", nil }, nil) @@ -360,16 +360,16 @@ func TestNowRunsAllHandlersAndEventResultReturnsFirstValidResult(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionFirst, }) lateCalled := false - bus.OnEventName("CompletionNowAllEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowAllEvent", "baseevent_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return abxbus.NewBaseEvent("NowAllChildEvent", nil), nil }, nil) - bus.OnEventName("CompletionNowAllEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowAllEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.OnEventName("CompletionNowAllEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowAllEvent", "winner_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - bus.OnEventName("CompletionNowAllEvent", "late_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowAllEvent", "late_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { lateCalled = true return "late", nil }, nil) @@ -394,7 +394,7 @@ func TestNowRunsAllHandlersAndEventResultReturnsFirstValidResult(t *testing.T) { func TestEventNowDefaultErrorPolicy(t *testing.T) { noHandlerBus := abxbus.NewEventBus("CompletionNowNoHandlerBus", nil) - noHandlerEvent, err := noHandlerBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() + noHandlerEvent, err := noHandlerBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -403,10 +403,10 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } noneBus := abxbus.NewEventBus("CompletionNowNoneBus", nil) - noneBus.OnEventName("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + noneBus.On("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - noneEvent, err := noneBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() + noneEvent, err := noneBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -415,13 +415,13 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } allErrorBus := abxbus.NewEventBus("CompletionNowAllErrorBus", nil) - allErrorBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + allErrorBus.On("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 1") }, nil) - allErrorBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_two", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + allErrorBus.On("CompletionNowErrorPolicyEvent", "fail_two", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 2") }, nil) - allErrorEvent, err := allErrorBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() + allErrorEvent, err := allErrorBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -430,13 +430,13 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } mixedValidBus := abxbus.NewEventBus("CompletionNowMixedValidBus", nil) - mixedValidBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedValidBus.On("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 1") }, nil) - mixedValidBus.OnEventName("CompletionNowErrorPolicyEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedValidBus.On("CompletionNowErrorPolicyEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "winner", nil }, nil) - mixedValidEvent, err := mixedValidBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() + mixedValidEvent, err := mixedValidBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -445,13 +445,13 @@ func TestEventNowDefaultErrorPolicy(t *testing.T) { } mixedNoneBus := abxbus.NewEventBus("CompletionNowMixedNoneBus", nil) - mixedNoneBus.OnEventName("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedNoneBus.On("CompletionNowErrorPolicyEvent", "fail_one", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now boom 1") }, nil) - mixedNoneBus.OnEventName("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + mixedNoneBus.On("CompletionNowErrorPolicyEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - mixedNoneEvent, err := mixedNoneBus.EmitEventName("CompletionNowErrorPolicyEvent", nil).Now() + mixedNoneEvent, err := mixedNoneBus.Emit(abxbus.NewBaseEvent("CompletionNowErrorPolicyEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -464,17 +464,17 @@ func TestEventResultOptionsMatchEventResultsShape(t *testing.T) { bus := abxbus.NewEventBus("CompletionNowOptionsBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) - bus.OnEventName("CompletionNowOptionsEvent", "fail_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowOptionsEvent", "fail_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("now option boom") }, nil) - bus.OnEventName("CompletionNowOptionsEvent", "first_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowOptionsEvent", "first_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.OnEventName("CompletionNowOptionsEvent", "second_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowOptionsEvent", "second_valid", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "second", nil }, nil) - event, err := bus.EmitEventName("CompletionNowOptionsEvent", nil).Now() + event, err := bus.Emit(abxbus.NewBaseEvent("CompletionNowOptionsEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -482,7 +482,7 @@ func TestEventResultOptionsMatchEventResultsShape(t *testing.T) { t.Fatalf("RaiseIfAny=true should surface handler errors, got %v", err) } - filteredEvent, err := bus.EmitEventName("CompletionNowOptionsEvent", nil).Now() + filteredEvent, err := bus.Emit(abxbus.NewBaseEvent("CompletionNowOptionsEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -504,16 +504,16 @@ func TestEventResultReturnsFirstValidResultByRegistrationOrderAfterNow(t *testin bus := abxbus.NewEventBus("CompletionNowRegistrationOrderBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.OnEventName("CompletionNowRegistrationOrderEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowRegistrationOrderEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(50 * time.Millisecond) return "slow", nil }, nil) - bus.OnEventName("CompletionNowRegistrationOrderEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionNowRegistrationOrderEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(time.Millisecond) return "fast", nil }, nil) - event, err := bus.EmitEventName("CompletionNowRegistrationOrderEvent", nil).Now() + event, err := bus.Emit(abxbus.NewBaseEvent("CompletionNowRegistrationOrderEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -527,10 +527,10 @@ func TestEventHandlerCompletionFirstReturnsNoneWhenAllHandlersFail(t *testing.T) bus := abxbus.NewEventBus("CompletionAllFailBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.OnEventName("CompletionAllFailEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionAllFailEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("boom1") }, nil) - bus.OnEventName("CompletionAllFailEvent", "fail_slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionAllFailEvent", "fail_slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return nil, assertErr("boom2") }, nil) @@ -551,10 +551,10 @@ func TestEventHandlerCompletionFirstResultOptionsMatchEventResultOptions(t *test bus := abxbus.NewEventBus("CompletionFirstOptionsBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.OnEventName("CompletionFirstOptionsEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstOptionsEvent", "fail_fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, assertErr("first option boom") }, nil) - bus.OnEventName("CompletionFirstOptionsEvent", "slow_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstOptionsEvent", "slow_winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "winner", nil }, nil) @@ -581,7 +581,7 @@ func TestEventHandlerCompletionFirstResultOptionsMatchEventResultOptions(t *test } noneBus := abxbus.NewEventBus("CompletionFirstRaiseNoneBus", nil) - noneBus.OnEventName("CompletionFirstRaiseNoneEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + noneBus.On("CompletionFirstRaiseNoneEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) noneEvent := abxbus.NewBaseEvent("CompletionFirstRaiseNoneEvent", nil) @@ -601,7 +601,7 @@ func TestNowFirstResultTimeoutLimitsProcessingWait(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, EventTimeout: &noTimeout, }) - bus.OnEventName("CompletionFirstTimeoutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstTimeoutEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(500 * time.Millisecond) return "slow", nil }, nil) @@ -621,10 +621,10 @@ func TestEventResultIncludeCallbackReceivesResultAndEventResult(t *testing.T) { }) seenHandlerNames := []string{} seenResults := []any{} - bus.OnEventName("CompletionFirstIncludeEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstIncludeEvent", "none_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.OnEventName("CompletionFirstIncludeEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstIncludeEvent", "second_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "second", nil }, nil) @@ -661,14 +661,14 @@ func TestEventResultsIncludeCallbackReceivesResultAndEventResult(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) seenPairs := []string{} - bus.OnEventName("CompletionResultsListIncludeEvent", "keep_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionResultsListIncludeEvent", "keep_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "keep", nil }, nil) - bus.OnEventName("CompletionResultsListIncludeEvent", "drop_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionResultsListIncludeEvent", "drop_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "drop", nil }, nil) - event, err := bus.EmitEventName("CompletionResultsListIncludeEvent", nil).Now() + event, err := bus.Emit(abxbus.NewBaseEvent("CompletionResultsListIncludeEvent", nil)).Now() if err != nil { t.Fatal(err) } @@ -695,16 +695,16 @@ func TestEventResultReturnsFirstCurrentResultWithFirstResultWait(t *testing.T) { bus := abxbus.NewEventBus("CompletionFirstCurrentResultBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.OnEventName("CompletionFirstCurrentResultEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstCurrentResultEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(50 * time.Millisecond) return "slow", nil }, nil) - bus.OnEventName("CompletionFirstCurrentResultEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstCurrentResultEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(time.Millisecond) return "fast", nil }, nil) - event := bus.EmitEventName("CompletionFirstCurrentResultEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("CompletionFirstCurrentResultEvent", nil)) if _, err := event.Now(&abxbus.EventWaitOptions{FirstResult: true}); err != nil { t.Fatal(err) } @@ -719,11 +719,11 @@ func TestEventResultRaiseIfAnyIncludesFirstModeControlErrors(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) - bus.OnEventName("CompletionFirstControlErrorEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstControlErrorEvent", "fast_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) return "fast", nil }, nil) - bus.OnEventName("CompletionFirstControlErrorEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CompletionFirstControlErrorEvent", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(500 * time.Millisecond): return "slow", nil diff --git a/abxbus-go/tests/event_handler_test.go b/abxbus-go/tests/event_handler_test.go index e66e79fb..46554d69 100644 --- a/abxbus-go/tests/event_handler_test.go +++ b/abxbus-go/tests/event_handler_test.go @@ -49,47 +49,52 @@ func TestEventHandlerJSONRoundtrip(t *testing.T) { func TestEventBusOnSupportsEventFirstOptionalContextHandlerSignatures(t *testing.T) { bus := abxbus.NewEventBus("HandlerSignatureBus", nil) seen := []string{} + type handlerSignatureResult struct { + Source string + } - bus.OnEventName("HandlerSignatureEvent", "value_error", func(event *abxbus.BaseEvent) (any, error) { - seen = append(seen, event.EventType+":value_error") - return "value_error", nil + bus.On("HandlerSignatureEvent", "handler_a", func(event *abxbus.BaseEvent) (handlerSignatureResult, error) { + seen = append(seen, event.EventType+":handler_a") + return handlerSignatureResult{Source: "event"}, nil }, nil) - bus.OnEventName("HandlerSignatureEvent", "value_error_ctx", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("HandlerSignatureEvent", "handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (handlerSignatureResult, error) { if ctx == nil { t.Fatal("context should be available when requested") } - seen = append(seen, event.EventType+":value_error_ctx") - return "value_error_ctx", nil + seen = append(seen, event.EventType+":handler_b") + return handlerSignatureResult{Source: "context"}, nil }, nil) - bus.OnEventName("HandlerSignatureEvent", "error_only", func(event *abxbus.BaseEvent) error { - seen = append(seen, event.EventType+":error_only") + bus.On("HandlerSignatureEvent", "handler_c", func(event *abxbus.BaseEvent) error { + seen = append(seen, event.EventType+":handler_c") return nil }, nil) - bus.OnEventName("HandlerSignatureEvent", "error_only_ctx", func(event *abxbus.BaseEvent, ctx context.Context) error { + bus.On("HandlerSignatureEvent", "handler_d", func(event *abxbus.BaseEvent, ctx context.Context) error { if ctx == nil { t.Fatal("context should be available when requested") } - seen = append(seen, event.EventType+":error_only_ctx") + seen = append(seen, event.EventType+":handler_d") return nil }, nil) - bus.OnEventName("HandlerSignatureEvent", "void", func(event *abxbus.BaseEvent) { - seen = append(seen, event.EventType+":void") + bus.On("HandlerSignatureEvent", "handler_e", func(event *abxbus.BaseEvent) { + seen = append(seen, event.EventType+":handler_e") }, nil) - bus.OnEventName("HandlerSignatureEvent", "void_ctx", func(event *abxbus.BaseEvent, ctx context.Context) { + bus.On("HandlerSignatureEvent", "handler_f", func(event *abxbus.BaseEvent, ctx context.Context) { if ctx == nil { t.Fatal("context should be available when requested") } - seen = append(seen, event.EventType+":void_ctx") + seen = append(seen, event.EventType+":handler_f") }, nil) - values, err := bus.EmitEventName("HandlerSignatureEvent", nil).EventResultsList(&abxbus.EventResultOptions{ + values, err := bus.Emit(abxbus.NewBaseEvent("HandlerSignatureEvent", nil)).EventResultsList(&abxbus.EventResultOptions{ RaiseIfAny: false, RaiseIfNone: true, }) if err != nil { t.Fatal(err) } - if len(values) != 2 || values[0] != "value_error" || values[1] != "value_error_ctx" { + if len(values) != 2 || + values[0] != (handlerSignatureResult{Source: "event"}) || + values[1] != (handlerSignatureResult{Source: "context"}) { t.Fatalf("expected only non-null handler values, got %#v", values) } if len(seen) != 6 { @@ -111,16 +116,16 @@ func TestEventBusOnTreatsTypedNilHandlersAsNoop(t *testing.T) { var voidCtx func(*abxbus.BaseEvent, context.Context) var named nilNamedHandler - bus.OnEventName("TypedNilHandlerEvent", "direct", direct, nil) - bus.OnEventName("TypedNilHandlerEvent", "value_error", valueError, nil) - bus.OnEventName("TypedNilHandlerEvent", "value_error_ctx", valueErrorCtx, nil) - bus.OnEventName("TypedNilHandlerEvent", "error_only", errorOnly, nil) - bus.OnEventName("TypedNilHandlerEvent", "error_only_ctx", errorOnlyCtx, nil) - bus.OnEventName("TypedNilHandlerEvent", "void", voidOnly, nil) - bus.OnEventName("TypedNilHandlerEvent", "void_ctx", voidCtx, nil) - bus.OnEventName("TypedNilHandlerEvent", "named", named, nil) + bus.On("TypedNilHandlerEvent", "direct", direct, nil) + bus.On("TypedNilHandlerEvent", "handler_a", valueError, nil) + bus.On("TypedNilHandlerEvent", "handler_b", valueErrorCtx, nil) + bus.On("TypedNilHandlerEvent", "handler_c", errorOnly, nil) + bus.On("TypedNilHandlerEvent", "handler_d", errorOnlyCtx, nil) + bus.On("TypedNilHandlerEvent", "handler_e", voidOnly, nil) + bus.On("TypedNilHandlerEvent", "handler_f", voidCtx, nil) + bus.On("TypedNilHandlerEvent", "named", named, nil) - values, err := bus.EmitEventName("TypedNilHandlerEvent", nil).EventResultsList(&abxbus.EventResultOptions{ + values, err := bus.Emit(abxbus.NewBaseEvent("TypedNilHandlerEvent", nil)).EventResultsList(&abxbus.EventResultOptions{ RaiseIfAny: true, RaiseIfNone: false, }) @@ -132,6 +137,30 @@ func TestEventBusOnTreatsTypedNilHandlersAsNoop(t *testing.T) { } } +func TestEventBusOnAndEmitInferTypesFromHandlerAndEvent(t *testing.T) { + type InferredOnEvent struct { + A int `json:"a"` + B int `json:"b"` + } + + bus := abxbus.NewEventBus("InferredOnBus", nil) + bus.On(func(payload InferredOnEvent) (int, error) { + return payload.A + payload.B, nil + }) + + event := bus.Emit(InferredOnEvent{A: 2, B: 3}) + if event.EventType != "InferredOnEvent" { + t.Fatalf("event type should be inferred from emitted struct, got %s", event.EventType) + } + result, err := event.EventResult() + if err != nil { + t.Fatal(err) + } + if result != 5 { + t.Fatalf("handler result should come from typed callback return, got %#v", result) + } +} + // Folded from event_handler_ids_test.go to keep test layout class-based. func TestBusAndEventIDsAreUUIDv7(t *testing.T) { bus := abxbus.NewEventBus("BusId", nil) @@ -183,7 +212,7 @@ func TestOnRecomputesHandlerIDAfterMetadataOverrides(t *testing.T) { expectedID := "19ea9fe8-cfbe-541e-8a35-2579e4e9efff" bus := abxbus.NewEventBus("StandaloneBus", &abxbus.EventBusOptions{ID: eventbusID}) - entry := bus.OnEventName(eventPattern, "original_name", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + entry := bus.On(eventPattern, "original_name", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, &abxbus.EventHandler{ HandlerName: handlerName, diff --git a/abxbus-go/tests/event_result_test.go b/abxbus-go/tests/event_result_test.go index 36239f73..c8a828e6 100644 --- a/abxbus-go/tests/event_result_test.go +++ b/abxbus-go/tests/event_result_test.go @@ -178,14 +178,14 @@ func TestEventResultAllErrorOptionsContract(t *testing.T) { }) defer bus.Destroy() - bus.OnEventName("AllErrorResultOptionsEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("AllErrorResultOptionsEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("first failure") }, nil) - bus.OnEventName("AllErrorResultOptionsEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("AllErrorResultOptionsEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("second failure") }, nil) - event := bus.EmitEventName("AllErrorResultOptionsEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("AllErrorResultOptionsEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -230,11 +230,11 @@ func TestEventResultAllErrorOptionsContract(t *testing.T) { func TestEventResultDefaultOptionsContract(t *testing.T) { errorBus := abxbus.NewEventBus("EventResultDefaultErrorOptionsBus", nil) - errorBus.OnEventName("DefaultErrorOptionsEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + errorBus.On("DefaultErrorOptionsEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("default boom") }, nil) - errorEvent := errorBus.EmitEventName("DefaultErrorOptionsEvent", nil) + errorEvent := errorBus.Emit(abxbus.NewBaseEvent("DefaultErrorOptionsEvent", nil)) if _, err := errorEvent.Now(); err != nil { t.Fatal(err) } @@ -260,7 +260,7 @@ func TestEventResultDefaultOptionsContract(t *testing.T) { errorBus.Destroy() emptyBus := abxbus.NewEventBus("EventResultDefaultNoneOptionsBus", nil) - emptyEvent := emptyBus.EmitEventName("DefaultNoneOptionsEvent", nil) + emptyEvent := emptyBus.Emit(abxbus.NewBaseEvent("DefaultNoneOptionsEvent", nil)) if _, err := emptyEvent.Now(); err != nil { t.Fatal(err) } @@ -283,17 +283,17 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { bus := abxbus.NewEventBus("EventResultErrorShapeBus", &abxbus.EventBusOptions{ EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - bus.OnEventName("SingleErrorEvent", "single", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SingleErrorEvent", "single", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("single shape failure") }, nil) - bus.OnEventName("MultiErrorEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MultiErrorEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("first shape failure") }, nil) - bus.OnEventName("MultiErrorEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MultiErrorEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("second shape failure") }, nil) - single := bus.EmitEventName("SingleErrorEvent", nil) + single := bus.Emit(abxbus.NewBaseEvent("SingleErrorEvent", nil)) if _, err := single.Now(); err != nil { t.Fatal(err) } @@ -306,7 +306,7 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { t.Fatalf("single handler failure should not use EventHandlerErrors, got %#v", singleHandlerErrors) } - event := bus.EmitEventName("MultiErrorEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("MultiErrorEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -326,7 +326,7 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { } emptyBus := abxbus.NewEventBus("EventResultNoneShapeBus", nil) - empty := emptyBus.EmitEventName("EmptyResultEvent", nil) + empty := emptyBus.Emit(abxbus.NewBaseEvent("EmptyResultEvent", nil)) if _, err := empty.Now(); err != nil { t.Fatal(err) } @@ -346,11 +346,11 @@ func TestEventResultErrorShapesUseSingleExceptionOrGroup(t *testing.T) { func TestEventResultOptions(t *testing.T) { bus := abxbus.NewEventBus("ResultsListBus", nil) - bus.OnEventName("ListEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.OnEventName("ListEvent", "nil", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.OnEventName("ListEvent", "err", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) + bus.On("ListEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) + bus.On("ListEvent", "nil", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) + bus.On("ListEvent", "err", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - e := bus.EmitEventName("ListEvent", nil) + e := bus.Emit(abxbus.NewBaseEvent("ListEvent", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -389,12 +389,12 @@ func TestEventResultOptions(t *testing.T) { slowBus := abxbus.NewEventBus("ResultsListTimeoutBus", nil) started := make(chan struct{}, 1) release := make(chan struct{}) - slowBus.OnEventName("SlowListEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + slowBus.On("SlowListEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return "late", nil }, nil) - slow := slowBus.EmitEventName("SlowListEvent", nil) + slow := slowBus.Emit(abxbus.NewBaseEvent("SlowListEvent", nil)) select { case <-started: case <-time.After(2 * time.Second): @@ -417,22 +417,22 @@ func TestEventResultAndResultsListUseRegistrationOrderForCurrentResultSubset(t * EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) completedOrder := make(chan string, 3) - bus.OnEventName("OrderResultEvent", "null", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("OrderResultEvent", "null", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) completedOrder <- "null" return nil, nil }, &abxbus.EventHandler{ID: "m-null"}) - bus.OnEventName("OrderResultEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("OrderResultEvent", "winner", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(20 * time.Millisecond) completedOrder <- "winner" return "winner", nil }, &abxbus.EventHandler{ID: "z-winner"}) - bus.OnEventName("OrderResultEvent", "late", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("OrderResultEvent", "late", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { completedOrder <- "late" return "late", nil }, &abxbus.EventHandler{ID: "a-late"}) - e := bus.EmitEventName("OrderResultEvent", nil) + e := bus.Emit(abxbus.NewBaseEvent("OrderResultEvent", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -563,14 +563,14 @@ func TestEventResultSerializesHandlerMetadataAndDerivedFields(t *testing.T) { bus := abxbus.NewEventBus("ResultMetadataBus", nil) timeout := 1.5 slowTimeout := 0.25 - handler := bus.OnEventName("MetadataEvent", "metadata_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.On("MetadataEvent", "metadata_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, &abxbus.EventHandler{ HandlerTimeout: &timeout, HandlerSlowTimeout: &slowTimeout, }) - event := bus.EmitEventName("MetadataEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("MetadataEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -614,7 +614,7 @@ func assertSchemaResult(t *testing.T, name string, schema map[string]any, value t.Helper() bus := abxbus.NewEventBus(name+"Bus", nil) eventType := name + "Event" - bus.OnEventName(eventType, "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On(eventType, "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return value, nil }, nil) event := bus.Emit(schemaEvent(eventType, schema)) @@ -651,7 +651,7 @@ func TestTypedResultSchemaValidatesHandlerResult(t *testing.T) { }, "required": []any{"value", "count"}, } - bus.OnEventName("TypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"value": "hello", "count": 42}, nil }, nil) @@ -667,10 +667,10 @@ func TestTypedResultSchemaValidatesHandlerResult(t *testing.T) { func TestBuiltinResultSchemaValidatesHandlerResults(t *testing.T) { bus := abxbus.NewEventBus("BuiltinResultSchemaBus", nil) - bus.OnEventName("BuiltinStringResultEvent", "string_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("BuiltinStringResultEvent", "string_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "42", nil }, nil) - bus.OnEventName("BuiltinIntResultEvent", "int_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("BuiltinIntResultEvent", "int_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return 123, nil }, nil) @@ -703,7 +703,7 @@ func TestInvalidHandlerResultMarksErrorWhenSchemaIsDefined(t *testing.T) { "required": []any{"value"}, "additionalProperties": false, } - bus.OnEventName("InvalidTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("InvalidTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"value": 123, "extra": true}, nil }, nil) @@ -723,11 +723,11 @@ func TestInvalidHandlerResultMarksErrorWhenSchemaIsDefined(t *testing.T) { func TestNoSchemaLeavesRawHandlerResultUntouched(t *testing.T) { bus := abxbus.NewEventBus("NoSchemaResultBus", nil) raw := map[string]any{"value": 123} - bus.OnEventName("NoSchemaEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NoSchemaEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return raw, nil }, nil) - event := bus.EmitEventName("NoSchemaEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("NoSchemaEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -760,7 +760,7 @@ func TestComplexResultSchemaValidatesNestedData(t *testing.T) { }, "required": []any{"items"}, } - bus.OnEventName("ComplexTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ComplexTypedResultEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"items": []any{map[string]any{"id": 1, "labels": []any{"a", "b"}}}}, nil }, nil) @@ -929,7 +929,7 @@ func TestSchemaReferencesAndAnyOfAreEnforced(t *testing.T) { }, "$ref": "#/$defs/Payload", } - bus.OnEventName("SchemaRefEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SchemaRefEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"value": 7}, nil }, nil) @@ -1085,16 +1085,16 @@ func TestEventBusOnSupportsNamedHandlerFunctionTypes(t *testing.T) { gotNoContext := false gotContext := false - bus.OnEventName("NamedNoContextHandlerEvent", "named_no_context", namedBaseNoContextHandler(func(event *abxbus.BaseEvent) error { + bus.On("NamedNoContextHandlerEvent", "named_no_context", namedBaseNoContextHandler(func(event *abxbus.BaseEvent) error { gotNoContext = event.EventType == "NamedNoContextHandlerEvent" return nil }), nil) - bus.OnEventName("NamedWithContextHandlerEvent", "named_with_context", namedBaseWithContextHandler(func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NamedWithContextHandlerEvent", "named_with_context", namedBaseWithContextHandler(func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { gotContext = event.EventType == "NamedWithContextHandlerEvent" && ctx != nil return "named-ok", nil }), nil) - noContextEvent := bus.EmitEventName("NamedNoContextHandlerEvent", nil) + noContextEvent := bus.Emit(abxbus.NewBaseEvent("NamedNoContextHandlerEvent", nil)) if _, err := noContextEvent.Now(); err != nil { t.Fatal(err) } @@ -1102,7 +1102,7 @@ func TestEventBusOnSupportsNamedHandlerFunctionTypes(t *testing.T) { t.Fatal("expected named no-context handler to run") } - contextEvent := bus.EmitEventName("NamedWithContextHandlerEvent", nil) + contextEvent := bus.Emit(abxbus.NewBaseEvent("NamedWithContextHandlerEvent", nil)) if _, err := contextEvent.Now(); err != nil { t.Fatal(err) } @@ -1195,7 +1195,7 @@ func TestEventPayloadAsRejectsNilEvent(t *testing.T) { func TestTypedEventWithResultSchemaValidatesHandlerReturnAtRuntime(t *testing.T) { bus := abxbus.NewEventBus("TypedSchemaBus", nil) - bus.OnEventName("TypedSchemaEvent", "bad", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TypedSchemaEvent", "bad", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"sum": "not-an-int"}, nil }, nil) @@ -1213,7 +1213,7 @@ func TestOnValidatesPayloadBeforeCallingHandler(t *testing.T) { return addResult{Sum: payload.A + payload.B}, nil }, nil) - event := bus.EmitEventName("TypedPayloadSchemaEvent", map[string]any{"a": 1}) + event := bus.Emit(abxbus.NewBaseEvent("TypedPayloadSchemaEvent", map[string]any{"a": 1})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1233,7 +1233,7 @@ func TestOnRejectsWrongPayloadFieldType(t *testing.T) { return addResult{Sum: payload.A + payload.B}, nil }, nil) - event := bus.EmitEventName("TypedPayloadTypeEvent", map[string]any{"a": "one", "b": 2}) + event := bus.Emit(abxbus.NewBaseEvent("TypedPayloadTypeEvent", map[string]any{"a": "one", "b": 2})) if _, err := event.Now(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_cross_runtime_features_test.go b/abxbus-go/tests/eventbus_cross_runtime_features_test.go index 5b090903..b19c1ffe 100644 --- a/abxbus-go/tests/eventbus_cross_runtime_features_test.go +++ b/abxbus-go/tests/eventbus_cross_runtime_features_test.go @@ -38,16 +38,16 @@ func TestQueueJumpPreservesParentChildLineageAndFindVisibility(t *testing.T) { executionOrder = append(executionOrder, value) } - bus.OnEventName("QueueJumpRootEvent", "on_root", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("QueueJumpRootEvent", "on_root", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendOrder("root:start") - child := event.EmitEventName("QueueJumpChildEvent", nil) + child := event.Emit(abxbus.NewBaseEvent("QueueJumpChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } appendOrder("root:end") return "root-ok", nil }, nil) - bus.OnEventName("QueueJumpChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("QueueJumpChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() childEventID = event.EventID mu.Unlock() @@ -59,13 +59,13 @@ func TestQueueJumpPreservesParentChildLineageAndFindVisibility(t *testing.T) { } return "child-ok", nil }, nil) - bus.OnEventName("QueueJumpSiblingEvent", "on_sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("QueueJumpSiblingEvent", "on_sibling", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendOrder("sibling") return "sibling-ok", nil }, nil) - root := bus.EmitEventName("QueueJumpRootEvent", nil) - sibling := bus.EmitEventName("QueueJumpSiblingEvent", nil) + root := bus.Emit(abxbus.NewBaseEvent("QueueJumpRootEvent", nil)) + sibling := bus.Emit(abxbus.NewBaseEvent("QueueJumpSiblingEvent", nil)) if _, err := root.Now(); err != nil { t.Fatal(err) } @@ -164,12 +164,12 @@ func TestConcurrencyIntersectionParallelEventsWithSerialHandlers(t *testing.T) { mu.Unlock() return "ok", nil } - bus.OnEventName("ConcurrencyIntersectionEvent", "tracked_handler_a", trackedHandler, nil) - bus.OnEventName("ConcurrencyIntersectionEvent", "tracked_handler_b", trackedHandler, nil) + bus.On("ConcurrencyIntersectionEvent", "tracked_handler_a", trackedHandler, nil) + bus.On("ConcurrencyIntersectionEvent", "tracked_handler_b", trackedHandler, nil) events := make([]*abxbus.BaseEvent, 0, 8) for idx := 0; idx < 8; idx++ { - events = append(events, bus.EmitEventName("ConcurrencyIntersectionEvent", map[string]any{"token": idx})) + events = append(events, bus.Emit(abxbus.NewBaseEvent("ConcurrencyIntersectionEvent", map[string]any{"token": idx}))) } for _, event := range events { if _, err := event.Wait(); err != nil { @@ -202,15 +202,15 @@ func TestTimeoutEnforcementDoesNotBreakFollowupProcessingOrQueueState(t *testing EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) t.Cleanup(bus.Destroy) - bus.OnEventName("TimeoutEnforcementEvent", "slow_handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutEnforcementEvent", "slow_handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, nil) - bus.OnEventName("TimeoutEnforcementEvent", "slow_handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutEnforcementEvent", "slow_handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, nil) - bus.OnEventName("TimeoutFollowupEvent", "followup_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutFollowupEvent", "followup_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "followup-ok", nil }, nil) @@ -231,7 +231,7 @@ func TestTimeoutEnforcementDoesNotBreakFollowupProcessingOrQueueState(t *testing } } - followup := bus.EmitEventName("TimeoutFollowupEvent", nil) + followup := bus.Emit(abxbus.NewBaseEvent("TimeoutFollowupEvent", nil)) if _, err := followup.Now(); err != nil { t.Fatal(err) } @@ -262,11 +262,11 @@ func TestZeroHistoryBackpressureWithFindFutureStillResolvesNewEvents(t *testing. MaxHistoryDrop: false, }) t.Cleanup(bus.Destroy) - bus.OnEventName("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok:" + event.Payload["value"].(string), nil }, nil) - first := bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "first"}) + first := bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "first"})) if _, err := first.Now(); err != nil { t.Fatal(err) } @@ -284,7 +284,7 @@ func TestZeroHistoryBackpressureWithFindFutureStillResolvesNewEvents(t *testing. capturedFutureID := make(chan string, 1) go func() { time.Sleep(20 * time.Millisecond) - futureEvent := bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "future"}) + futureEvent := bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "future"})) capturedFutureID <- futureEvent.EventID }() futureMatch, err := bus.FindEventName("ZeroHistoryEvent", func(event *abxbus.BaseEvent) bool { @@ -322,16 +322,16 @@ func TestContextPropagatesThroughForwardingAndChildDispatchWithLineageIntact(t * busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return busB.Emit(event), nil }, nil) - busB.OnEventName("ContextParentEvent", "on_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ContextParentEvent", "on_parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { capturedParentRequestID, _ = ctx.Value(key).(string) parentEventID = event.EventID - child := event.EmitEventName("ContextChildEvent", nil) + child := event.Emit(abxbus.NewBaseEvent("ContextChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } return "parent-ok", nil }, nil) - busB.OnEventName("ContextChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ContextChildEvent", "on_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { capturedChildRequestID, _ = ctx.Value(key).(string) if event.EventParentID != nil { childParentID = *event.EventParentID @@ -341,7 +341,7 @@ func TestContextPropagatesThroughForwardingAndChildDispatchWithLineageIntact(t * requestID := "fc81f432-98cd-7a06-824c-dafed74761bb" ctx := context.WithValue(context.Background(), key, requestID) - parent := busA.EmitEventNameWithContext(ctx, "ContextParentEvent", nil) + parent := busA.EmitWithContext(ctx, abxbus.NewBaseEvent("ContextParentEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -391,7 +391,7 @@ func TestPendingQueueFindVisibilityTransitionsToCompletedAfterRelease(t *testing started := make(chan struct{}) release := make(chan struct{}) var once sync.Once - bus.OnEventName("PendingVisibilityEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PendingVisibilityEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if event.Payload["tag"] == "blocking" { once.Do(func() { close(started) }) select { @@ -403,10 +403,10 @@ func TestPendingQueueFindVisibilityTransitionsToCompletedAfterRelease(t *testing return "ok:" + event.Payload["tag"].(string), nil }, nil) - blocking := bus.EmitEventName("PendingVisibilityEvent", map[string]any{"tag": "blocking"}) + blocking := bus.Emit(abxbus.NewBaseEvent("PendingVisibilityEvent", map[string]any{"tag": "blocking"})) testWaitForSignal(t, started, 2*time.Second, "blocking event start") - queued := bus.EmitEventName("PendingVisibilityEvent", map[string]any{"tag": "queued"}) + queued := bus.Emit(abxbus.NewBaseEvent("PendingVisibilityEvent", map[string]any{"tag": "queued"})) time.Sleep(10 * time.Millisecond) foundQueued, err := bus.FindEventName("PendingVisibilityEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["tag"] == "queued" @@ -439,12 +439,12 @@ func TestHistoryBackpressureRejectsOverflowAndPreservesFindableHistory(t *testin MaxHistoryDrop: false, }) t.Cleanup(bus.Destroy) - bus.OnEventName("BackpressureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("BackpressureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok:" + event.Payload["value"].(string), nil }, nil) - first := bus.EmitEventName("BackpressureEvent", map[string]any{"value": "first"}) - second := bus.EmitEventName("BackpressureEvent", map[string]any{"value": "second"}) + first := bus.Emit(abxbus.NewBaseEvent("BackpressureEvent", map[string]any{"value": "first"})) + second := bus.Emit(abxbus.NewBaseEvent("BackpressureEvent", map[string]any{"value": "second"})) if _, err := first.Now(); err != nil { t.Fatal(err) } @@ -471,7 +471,7 @@ func TestHistoryBackpressureRejectsOverflowAndPreservesFindableHistory(t *testin t.Fatalf("history size should remain capped after rejected overflow, got %d", bus.EventHistory.Size()) } }() - bus.EmitEventName("BackpressureEvent", map[string]any{"value": "overflow"}) + bus.Emit(abxbus.NewBaseEvent("BackpressureEvent", map[string]any{"value": "overflow"})) } func TestEventBusCrossRuntimeJSONFeaturesUseCanonicalShapes(t *testing.T) { @@ -479,7 +479,7 @@ func TestEventBusCrossRuntimeJSONFeaturesUseCanonicalShapes(t *testing.T) { bus := abxbus.NewEventBus("CrossRuntimeFeatureBus", &abxbus.EventBusOptions{ EventHandlerDetectFilePaths: &detectPaths, }) - handler := bus.OnEventName("CrossRuntimeFeatureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.On("CrossRuntimeFeatureEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"ok": true}, nil }, nil) event := abxbus.NewBaseEvent("CrossRuntimeFeatureEvent", map[string]any{"label": "go"}) diff --git a/abxbus-go/tests/eventbus_debounce_test.go b/abxbus-go/tests/eventbus_debounce_test.go index b78497f1..121cc7c8 100644 --- a/abxbus-go/tests/eventbus_debounce_test.go +++ b/abxbus-go/tests/eventbus_debounce_test.go @@ -15,20 +15,20 @@ func debounceEmitFallback(bus *abxbus.EventBus, eventType string, payload map[st if found != nil { return found } - return bus.EmitEventName(eventType, payload) + return bus.Emit(abxbus.NewBaseEvent(eventType, payload)) } func TestSimpleDebounceWithChildOfReusesRecentEvent(t *testing.T) { bus := abxbus.NewEventBus("DebounceBus", nil) - bus.OnEventName("ScreenshotEvent", "complete_screenshot", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ScreenshotEvent", "complete_screenshot", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "screenshot_done", nil }, nil) - parent := bus.EmitEventName("ParentEvent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } - child := parent.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) + child := parent.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) if _, err := child.Now(); err != nil { t.Fatal(err) } @@ -56,11 +56,11 @@ func TestSimpleDebounceWithChildOfReusesRecentEvent(t *testing.T) { func TestReturnsExistingFreshEvent(t *testing.T) { bus := abxbus.NewEventBus("DebounceFreshBus", nil) - bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) - original := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) + original := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) if _, err := original.Now(); err != nil { t.Fatal(err) } @@ -105,7 +105,7 @@ func TestAdvancedDebouncePrefersHistoryThenWaitsFutureThenDispatches(t *testing. }() go func() { time.Sleep(50 * time.Millisecond) - bus.EmitEventName("SyncEvent", nil) + bus.Emit(abxbus.NewBaseEvent("SyncEvent", nil)) }() ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) @@ -127,7 +127,7 @@ func TestAdvancedDebouncePrefersHistoryThenWaitsFutureThenDispatches(t *testing. resolved = futureMatch } if resolved == nil { - resolved = bus.EmitEventName("SyncEvent", nil) + resolved = bus.Emit(abxbus.NewBaseEvent("SyncEvent", nil)) } if _, err := resolved.Now(); err != nil { t.Fatal(err) @@ -139,7 +139,7 @@ func TestAdvancedDebouncePrefersHistoryThenWaitsFutureThenDispatches(t *testing. func TestDispatchesNewWhenNoMatch(t *testing.T) { bus := abxbus.NewEventBus("DebounceNoMatchBus", nil) - bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) @@ -163,11 +163,11 @@ func TestDispatchesNewWhenNoMatch(t *testing.T) { func TestDispatchesNewWhenStale(t *testing.T) { bus := abxbus.NewEventBus("DebounceStaleBus", nil) - bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) - original := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) + original := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) if _, err := original.Now(); err != nil { t.Fatal(err) } @@ -227,11 +227,11 @@ func TestFindPastFloatReturnsImmediatelyWithoutWaiting(t *testing.T) { func TestOrChainWithoutWaitingFindsExisting(t *testing.T) { bus := abxbus.NewEventBus("DebounceOrChainExistingBus", nil) - bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) - original := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1}) + original := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": debounceTargetID1})) if _, err := original.Now(); err != nil { t.Fatal(err) } @@ -257,7 +257,7 @@ func TestOrChainWithoutWaitingFindsExisting(t *testing.T) { func TestOrChainWithoutWaitingDispatchesWhenNoMatch(t *testing.T) { bus := abxbus.NewEventBus("DebounceOrChainNoMatchBus", nil) - bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) @@ -282,7 +282,7 @@ func TestOrChainWithoutWaitingDispatchesWhenNoMatch(t *testing.T) { func TestOrChainMultipleSequentialLookups(t *testing.T) { bus := abxbus.NewEventBus("DebounceSequentialBus", nil) - bus.OnEventName("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ScreenshotEvent", "complete", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "done", nil }, nil) diff --git a/abxbus-go/tests/eventbus_dispatch_contextvars_test.go b/abxbus-go/tests/eventbus_dispatch_contextvars_test.go index 97e1339d..9ffa8918 100644 --- a/abxbus-go/tests/eventbus_dispatch_contextvars_test.go +++ b/abxbus-go/tests/eventbus_dispatch_contextvars_test.go @@ -13,13 +13,13 @@ func TestAwaitedDispatchPropagatesContextIntoHandlers(t *testing.T) { bus := abxbus.NewEventBus("ContextDispatchBus", nil) key := contextKey("request_id") seen := "" - bus.OnEventName("ContextEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ContextEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen, _ = ctx.Value(key).(string) return "ok", nil }, nil) ctx := context.WithValue(context.Background(), key, "req-123") - if _, err := bus.EmitEventNameWithContext(ctx, "ContextEvent", nil).Now(); err != nil { + if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("ContextEvent", nil)).Now(); err != nil { t.Fatal(err) } if seen != "req-123" { @@ -31,20 +31,20 @@ func TestAwaitedChildDispatchPropagatesHandlerContext(t *testing.T) { bus := abxbus.NewEventBus("ContextChildBus", nil) key := contextKey("trace_id") childSeen := "" - bus.OnEventName("ParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := event.EmitEventName("ChildContextEvent", nil) + bus.On("ParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := event.Emit(abxbus.NewBaseEvent("ChildContextEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } return "parent", nil }, nil) - bus.OnEventName("ChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childSeen, _ = ctx.Value(key).(string) return "child", nil }, nil) ctx := context.WithValue(context.Background(), key, "trace-456") - if _, err := bus.EmitEventNameWithContext(ctx, "ParentContextEvent", nil).Now(); err != nil { + if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("ParentContextEvent", nil)).Now(); err != nil { t.Fatal(err) } if childSeen != "trace-456" { @@ -59,20 +59,20 @@ func TestWaitChildDispatchPreservesHandlerContext(t *testing.T) { }) key := contextKey("event_completed_trace_id") childSeen := "" - bus.OnEventName("EventCompletedParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := event.EmitEventName("EventCompletedChildContextEvent", nil) + bus.On("EventCompletedParentContextEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := event.Emit(abxbus.NewBaseEvent("EventCompletedChildContextEvent", nil)) if _, err := child.Wait(); err != nil { return nil, err } return "parent", nil }, nil) - bus.OnEventName("EventCompletedChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("EventCompletedChildContextEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childSeen, _ = ctx.Value(key).(string) return "child", nil }, nil) ctx := context.WithValue(context.Background(), key, "trace-789") - if _, err := bus.EmitEventNameWithContext(ctx, "EventCompletedParentContextEvent", nil).Now(); err != nil { + if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("EventCompletedParentContextEvent", nil)).Now(); err != nil { t.Fatal(err) } waitTimeout := 2.0 diff --git a/abxbus-go/tests/eventbus_dispatch_defaults_test.go b/abxbus-go/tests/eventbus_dispatch_defaults_test.go index 3ffdb7b3..602b7ab3 100644 --- a/abxbus-go/tests/eventbus_dispatch_defaults_test.go +++ b/abxbus-go/tests/eventbus_dispatch_defaults_test.go @@ -34,11 +34,11 @@ func TestEventConcurrencyRemainsUnsetOnDispatchAndResolvesDuringProcessing(t *te EventConcurrency: abxbus.EventConcurrencyParallel, }) defer bus.Destroy() - bus.OnEventName("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - implicit := bus.EmitEventName("PropagationEvent", nil) + implicit := bus.Emit(abxbus.NewBaseEvent("PropagationEvent", nil)) explicitNone := abxbus.NewBaseEvent("PropagationEvent", nil) explicitNone.EventConcurrency = "" explicitNone = bus.Emit(explicitNone) @@ -65,7 +65,7 @@ func TestEventConcurrencyClassOverrideBeatsBusDefault(t *testing.T) { EventConcurrency: abxbus.EventConcurrencyParallel, }) defer bus.Destroy() - bus.OnEventName("ConcurrencyOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ConcurrencyOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) @@ -108,11 +108,11 @@ func TestHandlerDefaultsRemainUnsetOnDispatchAndResolveDuringProcessing(t *testi EventHandlerCompletion: abxbus.EventHandlerCompletionFirst, }) defer bus.Destroy() - bus.OnEventName("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PropagationEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - implicit := bus.EmitEventName("PropagationEvent", nil) + implicit := bus.Emit(abxbus.NewBaseEvent("PropagationEvent", nil)) explicitNone := abxbus.NewBaseEvent("PropagationEvent", nil) explicitNone.EventHandlerConcurrency = "" explicitNone.EventHandlerCompletion = "" @@ -142,7 +142,7 @@ func TestHandlerClassOverrideBeatsBusDefault(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionFirst, }) defer bus.Destroy() - bus.OnEventName("HandlerOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("HandlerOverrideEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) diff --git a/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go b/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go index 9d617ea7..7b38a2cc 100644 --- a/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go +++ b/abxbus-go/tests/eventbus_dispatch_parent_tracking_test.go @@ -17,8 +17,8 @@ func TestQueueJumpProcessesChildInsideParentHandler(t *testing.T) { var capturedChild *abxbus.BaseEvent childProcessedBeforeParentReturn := false - bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - capturedChild = e.EmitEventName("Child", nil) + bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + capturedChild = e.Emit(abxbus.NewBaseEvent("Child", nil)) if _, err := capturedChild.Now(); err != nil { return nil, err } @@ -27,11 +27,11 @@ func TestQueueJumpProcessesChildInsideParentHandler(t *testing.T) { } return "parent", nil }, nil) - bus.OnEventName("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -82,17 +82,17 @@ func TestEventEmitWithoutAwaitTracksChildButDoesNotBlockParentCompletion(t *test releaseChild := make(chan struct{}) var capturedChild *abxbus.BaseEvent - bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - capturedChild = e.EmitEventName("Child", map[string]any{"mode": "unawaited"}) + bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + capturedChild = e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"mode": "unawaited"})) return "parent", nil }, nil) - bus.OnEventName("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Child", "on_child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { childStarted <- struct{}{} <-releaseChild return "child", nil }, nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { close(releaseChild) t.Fatal(err) @@ -143,17 +143,17 @@ func TestBusEmitInsideHandlerIsUntrackedBackgroundEvent(t *testing.T) { releaseBg := make(chan struct{}) var background *abxbus.BaseEvent - bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - background = bus.EmitEventName("Background", map[string]any{"mode": "untracked"}) + bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + background = bus.Emit(abxbus.NewBaseEvent("Background", map[string]any{"mode": "untracked"})) return "parent", nil }, nil) - bus.OnEventName("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { bgStarted <- struct{}{} <-releaseBg return "background", nil }, nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { close(releaseBg) t.Fatal(err) @@ -201,19 +201,19 @@ func TestAwaitedBusEmitInsideHandlerQueueJumpsButStaysUntrackedRootEvent(t *test var background *abxbus.BaseEvent backgroundCompletedBeforeParentReturn := false - bus.OnEventName("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - background = bus.EmitEventName("Background", map[string]any{"mode": "awaited"}) + bus.On("Parent", "on_parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + background = bus.Emit(abxbus.NewBaseEvent("Background", map[string]any{"mode": "awaited"})) if _, err := background.Now(); err != nil { return nil, err } backgroundCompletedBeforeParentReturn = background.EventStatus == "completed" return "parent", nil }, nil) - bus.OnEventName("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Background", "on_background", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "background", nil }, nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -246,21 +246,21 @@ func TestErroringParentHandlersStillTrackChildrenAndContinue(t *testing.T) { }) childEvents := []*abxbus.BaseEvent{} - bus.OnEventName("Parent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := e.EmitEventName("Child", map[string]any{"source": "failing"}) + bus.On("Parent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"source": "failing"})) childEvents = append(childEvents, child) return nil, errors.New("expected parent handler failure") }, nil) - bus.OnEventName("Parent", "success", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := e.EmitEventName("Child", map[string]any{"source": "success"}) + bus.On("Parent", "success", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"source": "success"})) childEvents = append(childEvents, child) return "success", nil }, nil) - bus.OnEventName("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -285,19 +285,19 @@ func TestEventChildrenTrackDirectAndNestedDescendants(t *testing.T) { var child *abxbus.BaseEvent var grandchild *abxbus.BaseEvent - bus.OnEventName("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child = e.EmitEventName("Child", map[string]any{"level": 1}) + bus.On("Parent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child = e.Emit(abxbus.NewBaseEvent("Child", map[string]any{"level": 1})) return "parent", nil }, nil) - bus.OnEventName("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - grandchild = e.EmitEventName("Grandchild", map[string]any{"level": 2}) + bus.On("Child", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + grandchild = e.Emit(abxbus.NewBaseEvent("Grandchild", map[string]any{"level": 2})) return "child", nil }, nil) - bus.OnEventName("Grandchild", "grandchild", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Grandchild", "grandchild", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "grandchild", nil }, nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_error_handling_test.go b/abxbus-go/tests/eventbus_error_handling_test.go index 0c0d8b3b..32ba0635 100644 --- a/abxbus-go/tests/eventbus_error_handling_test.go +++ b/abxbus-go/tests/eventbus_error_handling_test.go @@ -10,10 +10,10 @@ import ( func TestEventResultPropagatesHandlerError(t *testing.T) { bus := abxbus.NewEventBus("ErrBus", nil) - bus.OnEventName("ErrEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ErrEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - e := bus.EmitEventName("ErrEvent", nil) + e := bus.Emit(abxbus.NewBaseEvent("ErrEvent", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -25,11 +25,11 @@ func TestEventResultPropagatesHandlerError(t *testing.T) { func TestNowRaiseIfAnyOptions(t *testing.T) { bus := abxbus.NewEventBus("NowRaiseIfAnyBus", nil) - bus.OnEventName("NowErrorEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NowErrorEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - event := bus.EmitEventName("NowErrorEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("NowErrorEvent", nil)) if _, err := event.Now(); err != nil { t.Fatalf("Now should wait for completion without surfacing handler errors, got %v", err) } @@ -43,13 +43,13 @@ func TestNowRaiseIfAnyOptions(t *testing.T) { func TestEventCompletesWhenOneHandlerErrorsAndAnotherSucceeds(t *testing.T) { bus := abxbus.NewEventBus("ErrMixedBus", &abxbus.EventBusOptions{EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel}) - bus.OnEventName("MixedEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MixedEvent", "ok", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.OnEventName("MixedEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MixedEvent", "boom", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - e := bus.EmitEventName("MixedEvent", nil) + e := bus.Emit(abxbus.NewBaseEvent("MixedEvent", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -93,16 +93,16 @@ func TestSerialHandlerErrorDoesNotPreventLaterHandlers(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionAll, }) calls := []string{} - bus.OnEventName("MixedEvent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MixedEvent", "failing", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "failing") return nil, errors.New("expected failure") }, nil) - bus.OnEventName("MixedEvent", "working", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MixedEvent", "working", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "working") return "worked", nil }, nil) - event := bus.EmitEventName("MixedEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("MixedEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_find_test.go b/abxbus-go/tests/eventbus_find_test.go index b9fef837..de54a02e 100644 --- a/abxbus-go/tests/eventbus_find_test.go +++ b/abxbus-go/tests/eventbus_find_test.go @@ -15,7 +15,7 @@ type TypedFindEvent struct { func TestFindHistoryAndFuture(t *testing.T) { bus := abxbus.NewEventBus("FindBus", nil) - seed := bus.EmitEventName("ResponseEvent", map[string]any{"request_id": "abc"}) + seed := bus.Emit(abxbus.NewBaseEvent("ResponseEvent", map[string]any{"request_id": "abc"})) if _, err := seed.Now(); err != nil { t.Fatal(err) } @@ -32,7 +32,7 @@ func TestFindHistoryAndFuture(t *testing.T) { go func() { time.Sleep(20 * time.Millisecond) - bus.EmitEventName("FutureEvent", map[string]any{"request_id": "future"}) + bus.Emit(abxbus.NewBaseEvent("FutureEvent", map[string]any{"request_id": "future"})) }() future, err := bus.FindEventName("FutureEvent", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { @@ -75,9 +75,9 @@ func TestFindAndFilterDefaultToTypedEvents(t *testing.T) { } } -func TestEmitEventNameCoversRawStringEmission(t *testing.T) { - bus := abxbus.NewEventBus("EmitEventNameBus", nil) - event := bus.EmitEventName("RawStringEvent", map[string]any{"ok": true}) +func TestEmitRequiresEventObject(t *testing.T) { + bus := abxbus.NewEventBus("EmitRequiresEventObjectBus", nil) + event := bus.Emit(abxbus.NewBaseEvent("RawStringEvent", map[string]any{"ok": true})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -99,7 +99,7 @@ func TestFindReturnsNilWhenNoMatch(t *testing.T) { func TestFindDefaultPastOnlyNoFutureWait(t *testing.T) { bus := abxbus.NewEventBus("FindDefaultBus", nil) - seed := bus.EmitEventName("DefaultEvent", nil) + seed := bus.Emit(abxbus.NewBaseEvent("DefaultEvent", nil)) if _, err := seed.Now(); err != nil { t.Fatal(err) } @@ -114,7 +114,7 @@ func TestFindDefaultPastOnlyNoFutureWait(t *testing.T) { func TestFindFutureIgnoresPastEvents(t *testing.T) { bus := abxbus.NewEventBus("FindFutureIgnoresPastBus", nil) - prior := bus.EmitEventName("ParentEvent", nil) + prior := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := prior.Now(); err != nil { t.Fatal(err) } @@ -145,7 +145,7 @@ func TestFindPastFalseFutureFalseReturnsNilImmediately(t *testing.T) { func TestFindPastAndFutureWindowsAreIndependent(t *testing.T) { bus := abxbus.NewEventBus("FindWindowIndependentBus", nil) - oldEvent := bus.EmitEventName("ParentEvent", nil) + oldEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := oldEvent.Now(); err != nil { t.Fatal(err) } @@ -261,8 +261,8 @@ func TestFindSupportsMetadataAndPayloadEqualityFilters(t *testing.T) { func TestFindWherePredicateAndBusScopedHistory(t *testing.T) { busA := abxbus.NewEventBus("FindBusA", nil) busB := abxbus.NewEventBus("FindBusB", nil) - matchA := busA.EmitEventName("ScopedEvent", map[string]any{"source": "A", "value": 1}) - matchB := busB.EmitEventName("ScopedEvent", map[string]any{"source": "B", "value": 2}) + matchA := busA.Emit(abxbus.NewBaseEvent("ScopedEvent", map[string]any{"source": "A", "value": 1})) + matchB := busB.Emit(abxbus.NewBaseEvent("ScopedEvent", map[string]any{"source": "B", "value": 2})) if _, err := matchA.Now(); err != nil { t.Fatal(err) } @@ -294,7 +294,7 @@ func TestFindWherePredicateAndBusScopedHistory(t *testing.T) { func TestFindChildOfFilteringAndLineageTraversal(t *testing.T) { bus := abxbus.NewEventBus("FindChildBus", nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -342,13 +342,13 @@ func TestFindCanSeeInProgressEventInHistory(t *testing.T) { bus := abxbus.NewEventBus("FindInProgressBus", nil) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.OnEventName("SlowFindEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SlowFindEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return "ok", nil }, nil) - e := bus.EmitEventName("SlowFindEvent", nil) + e := bus.Emit(abxbus.NewBaseEvent("SlowFindEvent", nil)) select { case <-started: case <-time.After(2 * time.Second): @@ -377,7 +377,7 @@ func TestFindFutureIgnoresAlreadyDispatchedInFlightEventsWhenPastFalse(t *testin t.Cleanup(bus.Destroy) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.OnEventName("FutureInflightEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("FutureInflightEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} select { case <-release: @@ -387,7 +387,7 @@ func TestFindFutureIgnoresAlreadyDispatchedInFlightEventsWhenPastFalse(t *testin return "ok", nil }, nil) - event := bus.EmitEventName("FutureInflightEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("FutureInflightEvent", nil)) select { case <-started: case <-time.After(2 * time.Second): @@ -413,7 +413,7 @@ func TestFindFutureResolvesOnDispatchBeforeHandlersComplete(t *testing.T) { t.Cleanup(bus.Destroy) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.OnEventName("DispatchVisibleEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("DispatchVisibleEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} select { case <-release: @@ -425,7 +425,7 @@ func TestFindFutureResolvesOnDispatchBeforeHandlersComplete(t *testing.T) { go func() { time.Sleep(20 * time.Millisecond) - bus.EmitEventName("DispatchVisibleEvent", nil) + bus.Emit(abxbus.NewBaseEvent("DispatchVisibleEvent", nil)) }() match, err := bus.FindEventName("DispatchVisibleEvent", nil, &abxbus.FindOptions{Past: false, Future: 1.0}) if err != nil { @@ -477,8 +477,8 @@ func TestMultipleConcurrentFutureFindWaitersResolveCorrectEvents(t *testing.T) { }() time.Sleep(20 * time.Millisecond) - eventB := bus.EmitEventName("ConcurrentFindB", nil) - eventA := bus.EmitEventName("ConcurrentFindA", nil) + eventB := bus.Emit(abxbus.NewBaseEvent("ConcurrentFindB", nil)) + eventA := bus.Emit(abxbus.NewBaseEvent("ConcurrentFindA", nil)) select { case err := <-errs: @@ -512,11 +512,11 @@ func TestMultipleConcurrentFutureFindWaitersResolveCorrectEvents(t *testing.T) { func TestMaxHistorySizeZeroDisablesPastSearchButFutureFindStillResolves(t *testing.T) { zeroHistorySize := 0 bus := abxbus.NewEventBus("FindZeroHistoryBus", &abxbus.EventBusOptions{MaxHistorySize: &zeroHistorySize}) - bus.OnEventName("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ZeroHistoryEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok:" + event.Payload["value"].(string), nil }, nil) - first := bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "first"}) + first := bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "first"})) if _, err := first.Now(); err != nil { t.Fatal(err) } @@ -533,7 +533,7 @@ func TestMaxHistorySizeZeroDisablesPastSearchButFutureFindStillResolves(t *testi go func() { time.Sleep(20 * time.Millisecond) - bus.EmitEventName("ZeroHistoryEvent", map[string]any{"value": "future"}) + bus.Emit(abxbus.NewBaseEvent("ZeroHistoryEvent", map[string]any{"value": "future"})) }() future, err := bus.FindEventName("ZeroHistoryEvent", func(event *abxbus.BaseEvent) bool { return event.Payload["value"] == "future" @@ -554,8 +554,8 @@ func TestMaxHistorySizeZeroDisablesPastSearchButFutureFindStillResolves(t *testi func TestFindReturnsFirstFilterResult(t *testing.T) { bus := abxbus.NewEventBus("FindFilterFirstBus", nil) - first := bus.EmitEventName("ParentEvent", nil) - second := bus.EmitEventName("ParentEvent", nil) + first := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) + second := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := first.Now(); err != nil { t.Fatal(err) } @@ -582,8 +582,8 @@ func TestFindReturnsFirstFilterResult(t *testing.T) { func TestFindSupportsPayloadFieldNamedLimitViaEquals(t *testing.T) { bus := abxbus.NewEventBus("FindLimitFieldBus", nil) - noMatch := bus.EmitEventName("LimitFieldEvent", map[string]any{"limit": 3}) - target := bus.EmitEventName("LimitFieldEvent", map[string]any{"limit": 5}) + noMatch := bus.Emit(abxbus.NewBaseEvent("LimitFieldEvent", map[string]any{"limit": 3})) + target := bus.Emit(abxbus.NewBaseEvent("LimitFieldEvent", map[string]any{"limit": 5})) if _, err := noMatch.Now(); err != nil { t.Fatal(err) } @@ -655,9 +655,9 @@ func TestFilterReturnsEmptyArrayWhenNoMatches(t *testing.T) { func TestFilterReturnsPastMatchesNewestFirstAndRespectsLimit(t *testing.T) { bus := abxbus.NewEventBus("FilterPastBus", nil) - first := bus.EmitEventName("Work", map[string]any{"n": 1}) - second := bus.EmitEventName("Work", map[string]any{"n": 2}) - third := bus.EmitEventName("Work", map[string]any{"n": 3}) + first := bus.Emit(abxbus.NewBaseEvent("Work", map[string]any{"n": 1})) + second := bus.Emit(abxbus.NewBaseEvent("Work", map[string]any{"n": 2})) + third := bus.Emit(abxbus.NewBaseEvent("Work", map[string]any{"n": 3})) for _, event := range []*abxbus.BaseEvent{first, second, third} { if _, err := event.Now(); err != nil { t.Fatal(err) @@ -676,9 +676,9 @@ func TestFilterReturnsPastMatchesNewestFirstAndRespectsLimit(t *testing.T) { func TestFilterRespectsWherePredicateNewestFirst(t *testing.T) { bus := abxbus.NewEventBus("FilterWhereBus", nil) - first := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": "same"}) - other := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": "other"}) - second := bus.EmitEventName("ScreenshotEvent", map[string]any{"target_id": "same"}) + first := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": "same"})) + other := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": "other"})) + second := bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"target_id": "same"})) for _, event := range []*abxbus.BaseEvent{first, other, second} { if _, err := event.Now(); err != nil { t.Fatal(err) @@ -698,8 +698,8 @@ func TestFilterRespectsWherePredicateNewestFirst(t *testing.T) { func TestFilterWildcardMatchesAllEventTypesNewestFirst(t *testing.T) { bus := abxbus.NewEventBus("FilterWildcardBus", nil) - userEvent := bus.EmitEventName("UserActionEvent", map[string]any{"action": "login"}) - systemEvent := bus.EmitEventName("SystemEvent", nil) + userEvent := bus.Emit(abxbus.NewBaseEvent("UserActionEvent", map[string]any{"action": "login"})) + systemEvent := bus.Emit(abxbus.NewBaseEvent("SystemEvent", nil)) if _, err := userEvent.Now(); err != nil { t.Fatal(err) } @@ -718,12 +718,12 @@ func TestFilterWildcardMatchesAllEventTypesNewestFirst(t *testing.T) { func TestFilterPastWindowFiltersByAge(t *testing.T) { bus := abxbus.NewEventBus("FilterPastWindowBus", nil) - oldEvent := bus.EmitEventName("ParentEvent", nil) + oldEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := oldEvent.Now(); err != nil { t.Fatal(err) } time.Sleep(120 * time.Millisecond) - newEvent := bus.EmitEventName("ParentEvent", nil) + newEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := newEvent.Now(); err != nil { t.Fatal(err) } @@ -739,14 +739,14 @@ func TestFilterPastWindowFiltersByAge(t *testing.T) { func TestFilterFutureAppendsMatchAfterPastResults(t *testing.T) { bus := abxbus.NewEventBus("FilterFutureAppendBus", nil) - pastEvent := bus.EmitEventName("ParentEvent", nil) + pastEvent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := pastEvent.Now(); err != nil { t.Fatal(err) } go func() { time.Sleep(20 * time.Millisecond) - bus.EmitEventName("ParentEvent", nil) + bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) }() matches, err := bus.FilterEventName("ParentEvent", nil, &abxbus.FilterOptions{Past: true, Future: 0.5}) if err != nil { @@ -762,7 +762,7 @@ func TestFilterFutureAppendsMatchAfterPastResults(t *testing.T) { func TestFilterSupportsWhereEqualsWildcardChildAndFuture(t *testing.T) { bus := abxbus.NewEventBus("FilterOptionsBus", nil) - parent := bus.EmitEventName("Parent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("Parent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -772,7 +772,7 @@ func TestFilterSupportsWhereEqualsWildcardChildAndFuture(t *testing.T) { if _, err := child.Now(); err != nil { t.Fatal(err) } - bus.EmitEventName("Other", map[string]any{"kind": "target"}) + bus.Emit(abxbus.NewBaseEvent("Other", map[string]any{"kind": "target"})) childMatches, err := bus.FilterEventName("*", func(event *abxbus.BaseEvent) bool { return event.Payload["kind"] == "target" @@ -786,7 +786,7 @@ func TestFilterSupportsWhereEqualsWildcardChildAndFuture(t *testing.T) { go func() { time.Sleep(20 * time.Millisecond) - bus.EmitEventName("FutureWork", map[string]any{"kind": "future"}) + bus.Emit(abxbus.NewBaseEvent("FutureWork", map[string]any{"kind": "future"})) }() futureMatches, err := bus.FilterEventName("FutureWork", nil, &abxbus.FilterOptions{ Past: false, diff --git a/abxbus-go/tests/eventbus_forwarding_test.go b/abxbus-go/tests/eventbus_forwarding_test.go index d003ef85..f71931fb 100644 --- a/abxbus-go/tests/eventbus_forwarding_test.go +++ b/abxbus-go/tests/eventbus_forwarding_test.go @@ -21,15 +21,15 @@ func TestEventsForwardBetweenBusesWithoutDuplication(t *testing.T) { seenA := []string{} seenB := []string{} seenC := []string{} - busA.OnEventName("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenA = append(seenA, event.EventID) return "a", nil }, nil) - busB.OnEventName("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenB = append(seenB, event.EventID) return "b", nil }, nil) - busC.OnEventName("PingEvent", "seen_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busC.On("PingEvent", "seen_c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenC = append(seenC, event.EventID) return "c", nil }, nil) @@ -42,7 +42,7 @@ func TestEventsForwardBetweenBusesWithoutDuplication(t *testing.T) { return nil, nil }, nil) - event := busA.EmitEventName("PingEvent", map[string]any{"value": 1}) + event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 1})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -73,15 +73,15 @@ func TestTreeLevelHierarchyBubbling(t *testing.T) { seenParent := []string{} seenChild := []string{} seenSubchild := []string{} - parentBus.OnEventName("PingEvent", "parent_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parentBus.On("PingEvent", "parent_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenParent = append(seenParent, event.EventID) return nil, nil }, nil) - childBus.OnEventName("PingEvent", "child_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + childBus.On("PingEvent", "child_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenChild = append(seenChild, event.EventID) return nil, nil }, nil) - subchildBus.OnEventName("PingEvent", "subchild_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + subchildBus.On("PingEvent", "subchild_seen", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenSubchild = append(seenSubchild, event.EventID) return nil, nil }, nil) @@ -94,7 +94,7 @@ func TestTreeLevelHierarchyBubbling(t *testing.T) { return nil, nil }, nil) - bottom := subchildBus.EmitEventName("PingEvent", map[string]any{"value": 1}) + bottom := subchildBus.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 1})) if _, err := bottom.Now(); err != nil { t.Fatal(err) } @@ -111,7 +111,7 @@ func TestTreeLevelHierarchyBubbling(t *testing.T) { } seenParent, seenChild, seenSubchild = []string{}, []string{}, []string{} - middle := childBus.EmitEventName("PingEvent", map[string]any{"value": 2}) + middle := childBus.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 2})) if _, err := middle.Now(); err != nil { t.Fatal(err) } @@ -134,11 +134,11 @@ func TestForwardingDisambiguatesBusesThatShareTheSameName(t *testing.T) { seenA := []string{} seenB := []string{} - busA.OnEventName("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("PingEvent", "seen_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenA = append(seenA, event.EventID) return "a", nil }, nil) - busB.OnEventName("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("PingEvent", "seen_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seenB = append(seenB, event.EventID) return "b", nil }, nil) @@ -147,7 +147,7 @@ func TestForwardingDisambiguatesBusesThatShareTheSameName(t *testing.T) { return nil, nil }, nil) - event := busA.EmitEventName("PingEvent", map[string]any{"value": 99}) + event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 99})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -181,17 +181,17 @@ func TestAwaitEventNowWaitsForHandlersOnForwardedBuses(t *testing.T) { completionLog = append(completionLog, value) } - busA.OnEventName("PingEvent", "a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("PingEvent", "a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) record("A") return "a", nil }, nil) - busB.OnEventName("PingEvent", "b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("PingEvent", "b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) record("B") return "b", nil }, nil) - busC.OnEventName("PingEvent", "c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busC.On("PingEvent", "c", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(50 * time.Millisecond) record("C") return "c", nil @@ -205,7 +205,7 @@ func TestAwaitEventNowWaitsForHandlersOnForwardedBuses(t *testing.T) { return nil, nil }, nil) - event := busA.EmitEventName("PingEvent", map[string]any{"value": 2}) + event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 2})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -234,7 +234,7 @@ func TestCircularForwardingFromFirstPeerDoesNotLoop(t *testing.T) { defer peer3.Destroy() seen1, seen2, seen3 := registerCycle(t, peer1, peer2, peer3) - event := peer1.EmitEventName("PingEvent", map[string]any{"value": 42}) + event := peer1.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 42})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -260,14 +260,14 @@ func TestCircularForwardingFromMiddlePeerDoesNotLoop(t *testing.T) { defer peer3.Destroy() seen1, seen2, seen3 := registerCycle(t, peer1, peer2, peer3) - warmup := peer1.EmitEventName("PingEvent", map[string]any{"value": 42}) + warmup := peer1.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 42})) if _, err := warmup.Now(); err != nil { t.Fatal(err) } waitAllIdle(t, peer1, peer2, peer3) *seen1, *seen2, *seen3 = []string{}, []string{}, []string{} - event := peer2.EmitEventName("PingEvent", map[string]any{"value": 99}) + event := peer2.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 99})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -295,12 +295,12 @@ func TestAwaitEventNowWaitsWhenForwardingHandlerIsAsyncDelayed(t *testing.T) { busADone := false busBDone := false - busA.OnEventName("PingEvent", "handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("PingEvent", "handler_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(20 * time.Millisecond) busADone = true return nil, nil }, nil) - busB.OnEventName("PingEvent", "handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("PingEvent", "handler_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(10 * time.Millisecond) busBDone = true return nil, nil @@ -311,7 +311,7 @@ func TestAwaitEventNowWaitsWhenForwardingHandlerIsAsyncDelayed(t *testing.T) { return nil, nil }, nil) - event := busA.EmitEventName("PingEvent", map[string]any{"value": 3}) + event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"value": 3})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -334,10 +334,10 @@ func TestForwardingSameEventDoesNotSetSelfParentID(t *testing.T) { defer origin.Destroy() defer target.Destroy() - origin.OnEventName("SelfParentForwardEvent", "origin_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + origin.On("SelfParentForwardEvent", "origin_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "origin-ok", nil }, nil) - target.OnEventName("SelfParentForwardEvent", "target_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + target.On("SelfParentForwardEvent", "target_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "target-ok", nil }, nil) origin.OnEventName("*", "forward_to_target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { @@ -345,7 +345,7 @@ func TestForwardingSameEventDoesNotSetSelfParentID(t *testing.T) { return nil, nil }, nil) - event := origin.EmitEventName("SelfParentForwardEvent", nil) + event := origin.Emit(abxbus.NewBaseEvent("SelfParentForwardEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -386,7 +386,7 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { release := make(chan struct{}) var inheritedRef *abxbus.BaseEvent - busB.OnEventName("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { if e.EventTimeout != nil || e.EventHandlerConcurrency != "" || e.EventHandlerCompletion != "" { t.Fatalf("forwarded event should keep defaults unset in handler: %#v", e) } @@ -397,7 +397,7 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { appendEntry(mode + ":b1_end") return "b1", nil }, nil) - busB.OnEventName("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { if e.EventTimeout != nil || e.EventHandlerConcurrency != "" || e.EventHandlerCompletion != "" { t.Fatalf("forwarded event should keep defaults unset in handler: %#v", e) } @@ -407,8 +407,8 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { appendEntry(mode + ":b2_end") return "b2", nil }, nil) - busA.OnEventName("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - inherited := e.EmitEventName("ForwardedDefaultsChildEvent", map[string]any{"mode": "inherited"}) + busA.On("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + inherited := e.Emit(abxbus.NewBaseEvent("ForwardedDefaultsChildEvent", map[string]any{"mode": "inherited"})) inheritedRef = inherited busB.Emit(inherited) if _, err := inherited.Now(); err != nil { @@ -417,7 +417,7 @@ func TestForwardedEventUsesProcessingBusDefaults(t *testing.T) { return nil, nil }, nil) - top := busA.EmitEventName("ForwardedDefaultsTriggerEvent", nil) + top := busA.Emit(abxbus.NewBaseEvent("ForwardedDefaultsTriggerEvent", nil)) select { case <-h1Started: case <-time.After(2 * time.Second): @@ -477,7 +477,7 @@ func TestForwardedEventPreservesExplicitHandlerConcurrencyOverride(t *testing.T) h2Started := make(chan struct{}, 1) release := make(chan struct{}) - busB.OnEventName("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ForwardedDefaultsChildEvent", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mode := e.Payload["mode"].(string) appendEntry(mode + ":b1_start") h1Started <- struct{}{} @@ -485,15 +485,15 @@ func TestForwardedEventPreservesExplicitHandlerConcurrencyOverride(t *testing.T) appendEntry(mode + ":b1_end") return "b1", nil }, nil) - busB.OnEventName("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ForwardedDefaultsChildEvent", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mode := e.Payload["mode"].(string) appendEntry(mode + ":b2_start") h2Started <- struct{}{} appendEntry(mode + ":b2_end") return "b2", nil }, nil) - busA.OnEventName("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - override := e.EmitEventName("ForwardedDefaultsChildEvent", map[string]any{"mode": "override"}) + busA.On("ForwardedDefaultsTriggerEvent", "trigger", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + override := e.Emit(abxbus.NewBaseEvent("ForwardedDefaultsChildEvent", map[string]any{"mode": "override"})) override.EventHandlerConcurrency = abxbus.EventHandlerConcurrencySerial busB.Emit(override) if _, err := override.Now(); err != nil { @@ -502,7 +502,7 @@ func TestForwardedEventPreservesExplicitHandlerConcurrencyOverride(t *testing.T) return nil, nil }, nil) - top := busA.EmitEventName("ForwardedDefaultsTriggerEvent", nil) + top := busA.Emit(abxbus.NewBaseEvent("ForwardedDefaultsTriggerEvent", nil)) select { case <-h1Started: case <-time.After(2 * time.Second): @@ -550,20 +550,20 @@ func TestForwardedFirstModeUsesProcessingBusHandlerConcurrencyDefaults(t *testin busB.Emit(event) return nil, nil }, nil) - busB.OnEventName("ForwardedFirstDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ForwardedFirstDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLog("slow_start") time.Sleep(20 * time.Millisecond) appendLog("slow_end") return "slow", nil }, nil) - busB.OnEventName("ForwardedFirstDefaultsEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ForwardedFirstDefaultsEvent", "fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { appendLog("fast_start") time.Sleep(time.Millisecond) appendLog("fast_end") return "fast", nil }, nil) - event := busA.EmitEventName("ForwardedFirstDefaultsEvent", nil) + event := busA.Emit(abxbus.NewBaseEvent("ForwardedFirstDefaultsEvent", nil)) if _, err := event.Now(&abxbus.EventWaitOptions{FirstResult: true}); err != nil { t.Fatal(err) } @@ -587,15 +587,15 @@ func TestProxyDispatchAutoLinksChildEventsLikeEmit(t *testing.T) { bus := abxbus.NewEventBus("ProxyDispatchAutoLinkBus", nil) defer bus.Destroy() - bus.OnEventName("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - event.EmitEventName("ProxyDispatchChildEvent", nil) + bus.On("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + event.Emit(abxbus.NewBaseEvent("ProxyDispatchChildEvent", nil)) return "root", nil }, nil) - bus.OnEventName("ProxyDispatchChildEvent", "child_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ProxyDispatchChildEvent", "child_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - root := bus.EmitEventName("ProxyDispatchRootEvent", nil) + root := bus.Emit(abxbus.NewBaseEvent("ProxyDispatchRootEvent", nil)) if _, err := root.Now(); err != nil { t.Fatal(err) } @@ -614,12 +614,12 @@ func TestProxyDispatchOfSameEventDoesNotSelfParentOrSelfLinkChild(t *testing.T) bus := abxbus.NewEventBus("ProxyDispatchSameEventBus", nil) defer bus.Destroy() - bus.OnEventName("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ProxyDispatchRootEvent", "root_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { event.Emit(event) return "root", nil }, nil) - root := bus.EmitEventName("ProxyDispatchRootEvent", nil) + root := bus.Emit(abxbus.NewBaseEvent("ProxyDispatchRootEvent", nil)) if _, err := root.Now(); err != nil { t.Fatal(err) } @@ -639,7 +639,7 @@ func TestEventsAreProcessedInFIFOOrder(t *testing.T) { processedOrders := []int{} handlerStartTimes := []time.Time{} - bus.OnEventName("OrderEvent", "order_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("OrderEvent", "order_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { handlerStartTimes = append(handlerStartTimes, time.Now()) order := event.Payload["order"].(int) if order%2 == 0 { @@ -652,7 +652,7 @@ func TestEventsAreProcessedInFIFOOrder(t *testing.T) { }, nil) for order := 0; order < 10; order++ { - bus.EmitEventName("OrderEvent", map[string]any{"order": order}) + bus.Emit(abxbus.NewBaseEvent("OrderEvent", map[string]any{"order": order})) } waitAllIdle(t, bus) @@ -672,15 +672,15 @@ func registerCycle(t *testing.T, peer1, peer2, peer3 *abxbus.EventBus) (*[]strin seen1 := []string{} seen2 := []string{} seen3 := []string{} - peer1.OnEventName("PingEvent", "seen_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer1.On("PingEvent", "seen_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen1 = append(seen1, event.EventID) return "p1", nil }, nil) - peer2.OnEventName("PingEvent", "seen_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer2.On("PingEvent", "seen_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen2 = append(seen2, event.EventID) return "p2", nil }, nil) - peer3.OnEventName("PingEvent", "seen_3", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + peer3.On("PingEvent", "seen_3", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { seen3 = append(seen3, event.EventID) return "p3", nil }, nil) diff --git a/abxbus-go/tests/eventbus_locking_test.go b/abxbus-go/tests/eventbus_locking_test.go index 05ae3f9c..5261bee2 100644 --- a/abxbus-go/tests/eventbus_locking_test.go +++ b/abxbus-go/tests/eventbus_locking_test.go @@ -38,12 +38,12 @@ func TestGlobalSerialAcrossBuses(t *testing.T) { } } - b1.OnEventName("Evt", "h1", h("b1"), nil) - b2.OnEventName("Evt", "h2", h("b2"), nil) + b1.On("Evt", "h1", h("b1"), nil) + b2.On("Evt", "h2", h("b2"), nil) for i := 1; i <= 3; i++ { - b1.EmitEventName("Evt", map[string]any{"n": i}) - b2.EmitEventName("Evt", map[string]any{"n": i}) + b1.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": i})) + b2.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": i})) } timeout := 2.0 @@ -96,22 +96,22 @@ func TestGlobalSerialAwaitedChildJumpsAheadOfQueuedEventsAcrossBuses(t *testing. order = append(order, value) } - busB.OnEventName("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("child_start") time.Sleep(5 * time.Millisecond) record("child_end") return "child", nil }, nil) - busB.OnEventName("QueuedEvent", "queued", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("QueuedEvent", "queued", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("queued_start") time.Sleep(time.Millisecond) record("queued_end") return "queued", nil }, nil) - busA.OnEventName("ParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("ParentEvent", "parent", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { record("parent_start") - busB.EmitEventName("QueuedEvent", nil) - child := e.EmitEventName("ChildEvent", nil) + busB.Emit(abxbus.NewBaseEvent("QueuedEvent", nil)) + child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) busB.Emit(child) record("child_dispatched") if _, err := child.Now(); err != nil { @@ -122,7 +122,7 @@ func TestGlobalSerialAwaitedChildJumpsAheadOfQueuedEventsAcrossBuses(t *testing. return "parent", nil }, nil) - parent := busA.EmitEventName("ParentEvent", nil) + parent := busA.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -181,12 +181,12 @@ func TestEventConcurrencyBusSerialSerializesPerBusButOverlapsAcrossBuses(t *test return label, nil } } - busA.OnEventName("Evt", "a", handler("a", startedA, releaseA), nil) - busB.OnEventName("Evt", "b", handler("b", startedB, releaseB), nil) + busA.On("Evt", "a", handler("a", startedA, releaseA), nil) + busB.On("Evt", "b", handler("b", startedB, releaseB), nil) - firstA := busA.EmitEventName("Evt", map[string]any{"n": 1}) - secondA := busA.EmitEventName("Evt", map[string]any{"n": 2}) - firstB := busB.EmitEventName("Evt", map[string]any{"n": 1}) + firstA := busA.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 1})) + secondA := busA.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 2})) + firstB := busB.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 1})) select { case <-startedA: @@ -236,7 +236,7 @@ func TestEventConcurrencyParallelAllowsSameBusEventsToOverlap(t *testing.T) { var mu sync.Mutex inFlight := 0 maxInFlight := 0 - bus.OnEventName("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -251,8 +251,8 @@ func TestEventConcurrencyParallelAllowsSameBusEventsToOverlap(t *testing.T) { return e.Payload["n"], nil }, nil) - first := bus.EmitEventName("Evt", map[string]any{"n": 1}) - second := bus.EmitEventName("Evt", map[string]any{"n": 2}) + first := bus.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 1})) + second := bus.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"n": 2})) for i := 0; i < 2; i++ { select { case <-started: @@ -290,7 +290,7 @@ func TestEventConcurrencyOverrideParallelBeatsBusSerialDefault(t *testing.T) { var mu sync.Mutex inFlight := 0 maxInFlight := 0 - bus.OnEventName("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -349,7 +349,7 @@ func TestEventConcurrencyOverrideBusSerialBeatsBusParallelDefault(t *testing.T) var mu sync.Mutex inFlight := 0 maxInFlight := 0 - bus.OnEventName("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -418,7 +418,7 @@ func TestHandlerConcurrencyParallelStartsBoth(t *testing.T) { started := make(chan struct{}, 2) for i := 0; i < 2; i++ { - bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { mu.Lock() count++ mu.Unlock() @@ -428,7 +428,7 @@ func TestHandlerConcurrencyParallelStartsBoth(t *testing.T) { }, nil) } - e := bus.EmitEventName("Evt", nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) deadline := time.After(2 * time.Second) for i := 0; i < 2; i++ { select { @@ -478,8 +478,8 @@ func TestEventHandlerConcurrencyPerEventOverrideControlsExecutionMode(t *testing mu.Unlock() return mode, nil } - bus.OnEventName("Evt", "first", handler, nil) - bus.OnEventName("Evt", "second", handler, nil) + bus.On("Evt", "first", handler, nil) + bus.On("Evt", "second", handler, nil) parallelEvent := abxbus.NewBaseEvent("Evt", map[string]any{"mode": "parallel"}) parallelEvent.EventHandlerConcurrency = abxbus.EventHandlerConcurrencyParallel diff --git a/abxbus-go/tests/eventbus_log_tree_test.go b/abxbus-go/tests/eventbus_log_tree_test.go index 1170dcd8..e892e6f4 100644 --- a/abxbus-go/tests/eventbus_log_tree_test.go +++ b/abxbus-go/tests/eventbus_log_tree_test.go @@ -11,18 +11,18 @@ import ( func TestLogTreeShowsParentChildAndHandlerResults(t *testing.T) { bus := abxbus.NewEventBus("TreeBus", nil) - bus.OnEventName("RootEvent", "root", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := e.EmitEventName("ChildEvent", nil) + bus.On("RootEvent", "root", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := e.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } return "root-ok", nil }, nil) - bus.OnEventName("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ChildEvent", "child", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child-ok", nil }, nil) - e := bus.EmitEventName("RootEvent", nil) + e := bus.Emit(abxbus.NewBaseEvent("RootEvent", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -39,7 +39,7 @@ func TestLogTreeShowsParentChildAndHandlerResults(t *testing.T) { func TestLogTreeIncludesTimedOutResultErrors(t *testing.T) { short := 0.01 bus := abxbus.NewEventBus("TimeoutTreeBus", &abxbus.EventBusOptions{EventTimeout: &short}) - bus.OnEventName("SlowEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SlowEvent", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(30 * time.Millisecond): return "too-late", nil @@ -47,7 +47,7 @@ func TestLogTreeIncludesTimedOutResultErrors(t *testing.T) { return nil, ctx.Err() } }, nil) - e := bus.EmitEventName("SlowEvent", nil) + e := bus.Emit(abxbus.NewBaseEvent("SlowEvent", nil)) if _, err := e.EventResult(); err == nil { t.Fatal("expected timeout error from event result") } diff --git a/abxbus-go/tests/eventbus_on_off_test.go b/abxbus-go/tests/eventbus_on_off_test.go index 24f72619..da1d45cd 100644 --- a/abxbus-go/tests/eventbus_on_off_test.go +++ b/abxbus-go/tests/eventbus_on_off_test.go @@ -13,11 +13,11 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { var eventCalls atomic.Int32 var wildcardCalls atomic.Int32 - h1 := bus.OnEventName("Evt", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + h1 := bus.On("Evt", "h1", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { eventCalls.Add(1) return "h1", nil }, nil) - h2 := bus.OnEventName("Evt", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + h2 := bus.On("Evt", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { eventCalls.Add(1) return "h2", nil }, nil) @@ -26,7 +26,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { return "all", nil }, nil) - e1 := bus.EmitEventName("Evt", nil) + e1 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e1.Now(); err != nil { t.Fatal(err) } @@ -38,7 +38,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("Evt", h1) - e2 := bus.EmitEventName("Evt", nil) + e2 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e2.Now(); err != nil { t.Fatal(err) } @@ -50,7 +50,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("Evt", h2.ID) - e3 := bus.EmitEventName("Evt", nil) + e3 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e3.Now(); err != nil { t.Fatal(err) } @@ -62,7 +62,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("Evt", nil) - e4 := bus.EmitEventName("Evt", nil) + e4 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e4.Now(); err != nil { t.Fatal(err) } @@ -71,7 +71,7 @@ func TestOnOffByEntryByIDAndRemoveAll(t *testing.T) { } bus.Off("*", nil) - e5 := bus.EmitEventName("Evt", nil) + e5 := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e5.Now(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_performance_test.go b/abxbus-go/tests/eventbus_performance_test.go index ee1954d6..d5778e2b 100644 --- a/abxbus-go/tests/eventbus_performance_test.go +++ b/abxbus-go/tests/eventbus_performance_test.go @@ -44,7 +44,7 @@ func TestPerformance50kEvents(t *testing.T) { var processed int64 var checksum int64 var expectedChecksum int64 - bus.OnEventName("PerfSimpleEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PerfSimpleEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&processed, 1) value, _ := event.Payload["value"].(int) batchID, _ := event.Payload["batch_id"].(int) @@ -57,7 +57,7 @@ func TestPerformance50kEvents(t *testing.T) { for i := 0; i < totalEvents; i++ { payload := map[string]any{"value": i, "batch_id": i % 17} expectedChecksum += int64(i + i%17) - pending = append(pending, bus.EmitEventName("PerfSimpleEvent", payload)) + pending = append(pending, bus.Emit(abxbus.NewBaseEvent("PerfSimpleEvent", payload))) if len(pending) >= batchSize { waitForPerformanceBatch(t, pending) pending = pending[:0] @@ -96,13 +96,13 @@ func TestPerformanceEphemeralBuses(t *testing.T) { MaxHistorySize: &historySize, MaxHistoryDrop: true, }) - bus.OnEventName("PerfEphemeralEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PerfEphemeralEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&processed, 1) return nil, nil }, nil) pending := make([]*abxbus.BaseEvent, 0, eventsPerBus) for eventIndex := 0; eventIndex < eventsPerBus; eventIndex++ { - pending = append(pending, bus.EmitEventName("PerfEphemeralEvent", nil)) + pending = append(pending, bus.Emit(abxbus.NewBaseEvent("PerfEphemeralEvent", nil))) } waitForPerformanceBatch(t, pending) timeout := 2.0 @@ -134,14 +134,14 @@ func TestPerformanceSingleEventManyParallelHandlers(t *testing.T) { var handled int64 for index := 0; index < totalHandlers; index++ { handlerID := fmt.Sprintf("perf-fixed-handler-%05d", index) - bus.OnEventName("PerfFixedHandlersEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PerfFixedHandlersEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&handled, 1) return nil, nil }, &abxbus.EventHandler{ID: handlerID}) } started := time.Now() - event := bus.EmitEventName("PerfFixedHandlersEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("PerfFixedHandlersEvent", nil)) waitForPerformanceBatch(t, []*abxbus.BaseEvent{event}) timeout := 10.0 if !bus.WaitUntilIdle(&timeout) { @@ -168,11 +168,11 @@ func TestPerformanceOnOffChurn(t *testing.T) { started := time.Now() for index := 0; index < totalEvents; index++ { handlerID := fmt.Sprintf("perf-one-off-handler-%05d", index) - handler := bus.OnEventName("PerfOneOffEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.On("PerfOneOffEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&handled, 1) return nil, nil }, &abxbus.EventHandler{ID: handlerID}) - event := bus.EmitEventName("PerfOneOffEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("PerfOneOffEvent", nil)) waitForPerformanceBatch(t, []*abxbus.BaseEvent{event}) bus.Off("PerfOneOffEvent", handler) } @@ -207,13 +207,13 @@ func TestPerformanceWorstCaseForwardingQueueJumpTimeouts(t *testing.T) { var parents int64 var children int64 var timedOut int64 - parentBus.OnEventName("WCParent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parentBus.On("WCParent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&parents, 1) - child := childBus.EmitEventName("WCChild", map[string]any{"parent": event.EventID, "iteration": event.Payload["iteration"]}) + child := childBus.Emit(abxbus.NewBaseEvent("WCChild", map[string]any{"parent": event.EventID, "iteration": event.Payload["iteration"]})) _, _ = child.Now() return nil, nil }, nil) - childBus.OnEventName("WCChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + childBus.On("WCChild", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { atomic.AddInt64(&children, 1) iteration, _ := event.Payload["iteration"].(int) if iteration%10 != 0 { @@ -231,7 +231,7 @@ func TestPerformanceWorstCaseForwardingQueueJumpTimeouts(t *testing.T) { pending := make([]*abxbus.BaseEvent, 0, 128) started := time.Now() for index := 0; index < totalEvents; index++ { - pending = append(pending, parentBus.EmitEventName("WCParent", map[string]any{"iteration": index})) + pending = append(pending, parentBus.Emit(abxbus.NewBaseEvent("WCParent", map[string]any{"iteration": index}))) if len(pending) >= cap(pending) { waitForPerformanceBatchAllowErrors(t, pending) pending = pending[:0] @@ -272,19 +272,19 @@ func TestPerformanceCleanupDestroyKeepsStateBounded(t *testing.T) { MaxHistorySize: &historySize, MaxHistoryDrop: true, }) - bus.OnEventName("CleanupEqEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CleanupEqEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) pending := make([]*abxbus.BaseEvent, 0, eventsPerBus) for eventIndex := 0; eventIndex < eventsPerBus; eventIndex++ { - pending = append(pending, bus.EmitEventName("CleanupEqEvent", nil)) + pending = append(pending, bus.Emit(abxbus.NewBaseEvent("CleanupEqEvent", nil))) } waitForPerformanceBatch(t, pending) bus.EventHistory.MaxHistorySize = &trimTarget bus.EventHistory.MaxHistoryDrop = true - trimEvent := bus.EmitEventName("CleanupEqTrimEvent", nil) + trimEvent := bus.Emit(abxbus.NewBaseEvent("CleanupEqTrimEvent", nil)) waitForPerformanceBatch(t, []*abxbus.BaseEvent{trimEvent}) timeout := 2.0 if !bus.WaitUntilIdle(&timeout) { @@ -346,7 +346,7 @@ func runFanoutBenchmark(t *testing.T, mode abxbus.EventHandlerConcurrencyMode) ( var handled int64 for index := 0; index < handlersPerEvent; index++ { handlerID := fmt.Sprintf("fanout-handler-%d", index) - bus.OnEventName("PerfFanoutEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("PerfFanoutEvent", handlerID, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(sleepDuration) atomic.AddInt64(&handled, 1) return nil, nil @@ -356,7 +356,7 @@ func runFanoutBenchmark(t *testing.T, mode abxbus.EventHandlerConcurrencyMode) ( pending := make([]*abxbus.BaseEvent, 0, 40) started := time.Now() for index := 0; index < totalEvents; index++ { - pending = append(pending, bus.EmitEventName("PerfFanoutEvent", nil)) + pending = append(pending, bus.Emit(abxbus.NewBaseEvent("PerfFanoutEvent", nil))) if len(pending) >= cap(pending) { waitForPerformanceBatch(t, pending) pending = pending[:0] diff --git a/abxbus-go/tests/eventbus_serialization_test.go b/abxbus-go/tests/eventbus_serialization_test.go index 2bb4e0e2..36e01219 100644 --- a/abxbus-go/tests/eventbus_serialization_test.go +++ b/abxbus-go/tests/eventbus_serialization_test.go @@ -39,8 +39,8 @@ func TestEventBusSerializationRoundtripPreservesConfigHandlersHistory(t *testing EventHandlerCompletion: abxbus.EventHandlerCompletionAll, EventHandlerSlowTimeout: &handlerSlowTimeout, }) - h := bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - e := bus.EmitEventName("Evt", map[string]any{"k": "v"}) + h := bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", map[string]any{"k": "v"})) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -113,8 +113,8 @@ func TestEventBusSerializationRoundtripPreservesConfigHandlersHistory(t *testing t.Fatalf("restored idle bus should start with clean runtime state") } - restored.OnEventName("Evt2", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok2", nil }, nil) - v, err := restored.EmitEventName("Evt2", nil).EventResult() + restored.On("Evt2", "h2", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok2", nil }, nil) + v, err := restored.Emit(abxbus.NewBaseEvent("Evt2", nil)).EventResult() if err != nil || v != "ok2" { t.Fatalf("restored bus should remain functional, result=%#v err=%v", v, err) } @@ -175,10 +175,10 @@ func TestEventBusFromJSONDefaultsMissingHandlerMaps(t *testing.T) { if err != nil { t.Fatal(err) } - restored.OnEventName("Evt", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + restored.On("Evt", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - result, err := restored.EmitEventName("Evt", nil).EventResult() + result, err := restored.Emit(abxbus.NewBaseEvent("Evt", nil)).EventResult() if err != nil { t.Fatal(err) } @@ -196,11 +196,11 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes }) originalOrder := []string{} - first := bus.OnEventName("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + first := bus.On("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { originalOrder = append(originalOrder, "first") return "first", nil }, nil) - second := bus.OnEventName("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + second := bus.On("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { originalOrder = append(originalOrder, "second") return "second", nil }, nil) @@ -219,7 +219,7 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes t.Fatalf("handlers_by_key order mismatch: got %v want %v", got, expectedIDs) } - if _, err := bus.EmitEventName("HandlerOrderEvent", nil).Now(); err != nil { + if _, err := bus.Emit(abxbus.NewBaseEvent("HandlerOrderEvent", nil)).Now(); err != nil { t.Fatal(err) } if len(originalOrder) != 2 || originalOrder[0] != "first" || originalOrder[1] != "second" { @@ -244,11 +244,11 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes } restoredOrder := []string{} - restored.OnEventName("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + restored.On("HandlerOrderEvent", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { restoredOrder = append(restoredOrder, "first") return "first", nil }, payload.Handlers[first.ID]) - restored.OnEventName("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + restored.On("HandlerOrderEvent", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { restoredOrder = append(restoredOrder, "second") return "second", nil }, payload.Handlers[second.ID]) @@ -265,7 +265,7 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes t.Fatalf("reattached handlers_by_key order mismatch: got %v want %v", got, expectedIDs) } - if _, err := restored.EmitEventName("HandlerOrderEvent", nil).Now(); err != nil { + if _, err := restored.Emit(abxbus.NewBaseEvent("HandlerOrderEvent", nil)).Now(); err != nil { t.Fatal(err) } if len(restoredOrder) != 2 || restoredOrder[0] != "first" || restoredOrder[1] != "second" { @@ -275,10 +275,10 @@ func TestEventBusSerializationPreservesHandlerRegistrationOrderThroughJSONAndRes func TestEventBusFromJSONRecreatesMissingHandlerEntriesFromEventResultMetadata(t *testing.T) { bus := abxbus.NewEventBus("MissingHandlerHydrationBus", nil) - bus.OnEventName("SerializableEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SerializableEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.EmitEventName("SerializableEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("SerializableEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -331,11 +331,11 @@ func TestEventBusFromJSONRecreatesMissingHandlerEntriesFromEventResultMetadata(t func TestBaseEventFromJSONRoundtripsRuntimeJSONShape(t *testing.T) { bus := abxbus.NewEventBus("SerializableBaseEventBus", nil) defer bus.Destroy() - bus.OnEventName("SerializableBaseEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SerializableBaseEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.EmitEventName("SerializableBaseEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("SerializableBaseEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -360,15 +360,15 @@ func TestEventBusSerializationPreservesPendingQueueIDs(t *testing.T) { bus := abxbus.NewEventBus("PendingSerBus", &abxbus.EventBusOptions{EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial}) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.OnEventName("BlockedEvt", "block", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("BlockedEvt", "block", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return "done", nil }, nil) - first := bus.EmitEventName("BlockedEvt", nil) + first := bus.Emit(abxbus.NewBaseEvent("BlockedEvt", nil)) <-started - second := bus.EmitEventName("BlockedEvt", nil) + second := bus.Emit(abxbus.NewBaseEvent("BlockedEvt", nil)) data, err := bus.ToJSON() if err != nil { diff --git a/abxbus-go/tests/eventbus_test.go b/abxbus-go/tests/eventbus_test.go index 9c094667..00ba9ab9 100644 --- a/abxbus-go/tests/eventbus_test.go +++ b/abxbus-go/tests/eventbus_test.go @@ -38,11 +38,11 @@ func TestEmitAndDispatchUseDefaultBehavior(t *testing.T) { } calls := []string{} - bus.OnEventName("CreateUserEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CreateUserEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "first") return "first", nil }, nil) - bus.OnEventName("CreateUserEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CreateUserEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { calls = append(calls, "second") return map[string]any{"user_id": "abc"}, nil }, nil) @@ -96,12 +96,12 @@ func TestUnboundedHistoryDisablesHistoryRejection(t *testing.T) { func TestMaxHistoryDropFalseRejectsNewDispatchWhenHistoryIsFull(t *testing.T) { maxHistorySize := 2 bus := abxbus.NewEventBus("NoDropHistBus", &abxbus.EventBusOptions{MaxHistorySize: &maxHistorySize}) - bus.OnEventName("NoDropEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("NoDropEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) for i := 1; i <= 2; i++ { - event := bus.EmitEventName("NoDropEvent", map[string]any{"seq": i}) + event := bus.Emit(abxbus.NewBaseEvent("NoDropEvent", map[string]any{"seq": i})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -122,7 +122,7 @@ func TestMaxHistoryDropFalseRejectsNewDispatchWhenHistoryIsFull(t *testing.T) { t.Fatalf("history should remain capped after rejected emit, got %d", bus.EventHistory.Size()) } }() - bus.EmitEventName("NoDropEvent", map[string]any{"seq": 3}) + bus.Emit(abxbus.NewBaseEvent("NoDropEvent", map[string]any{"seq": 3})) } func TestZeroHistorySizeKeepsInflightAndDropsOnCompletion(t *testing.T) { @@ -130,7 +130,7 @@ func TestZeroHistorySizeKeepsInflightAndDropsOnCompletion(t *testing.T) { bus := abxbus.NewEventBus("ZeroHistoryBus", &abxbus.EventBusOptions{MaxHistorySize: &zeroHistorySize}) started := make(chan struct{}, 1) release := make(chan struct{}) - bus.OnEventName("SlowEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SlowEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case started <- struct{}{}: default: @@ -139,14 +139,14 @@ func TestZeroHistorySizeKeepsInflightAndDropsOnCompletion(t *testing.T) { return "ok", nil }, nil) - first := bus.EmitEventName("SlowEvent", nil) + first := bus.Emit(abxbus.NewBaseEvent("SlowEvent", nil)) select { case <-started: case <-time.After(2 * time.Second): close(release) t.Fatal("timed out waiting for first handler to start") } - second := bus.EmitEventName("SlowEvent", nil) + second := bus.Emit(abxbus.NewBaseEvent("SlowEvent", nil)) if !bus.EventHistory.Has(first.EventID) || !bus.EventHistory.Has(second.EventID) { close(release) t.Fatalf("zero history should keep in-flight events, size=%d", bus.EventHistory.Size()) @@ -171,14 +171,14 @@ func TestZeroHistoryNoDropAllowsBurstQueueingAndDropsCompletedEvents(t *testing. zeroHistorySize := 0 bus := abxbus.NewEventBus("ZeroHistNoDropBus", &abxbus.EventBusOptions{MaxHistorySize: &zeroHistorySize, MaxHistoryDrop: false}) release := make(chan struct{}) - bus.OnEventName("BurstEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("BurstEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { <-release return "ok", nil }, nil) events := make([]*abxbus.BaseEvent, 0, 25) for i := 0; i < 25; i++ { - events = append(events, bus.EmitEventName("BurstEvent", map[string]any{"seq": i})) + events = append(events, bus.Emit(abxbus.NewBaseEvent("BurstEvent", map[string]any{"seq": i}))) } if bus.EventHistory.Size() == 0 { close(release) @@ -202,10 +202,10 @@ func TestZeroHistoryNoDropAllowsBurstQueueingAndDropsCompletedEvents(t *testing. func TestEventResultReturnsFirstCompletedResult(t *testing.T) { bus := abxbus.NewEventBus("SimpleBus", nil) - bus.OnEventName("ResultEvent", "on_create", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultEvent", "on_create", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return map[string]any{"user_id": "abc"}, nil }, nil) - e := bus.EmitEventName("ResultEvent", map[string]any{"email": "a@b.com"}) + e := bus.Emit(abxbus.NewBaseEvent("ResultEvent", map[string]any{"email": "a@b.com"})) result, err := e.EventResult() if err != nil { t.Fatal(err) @@ -223,16 +223,16 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( bus := abxbus.NewEventBus("EventResultsOptionsBus", nil) defer bus.Destroy() - bus.OnEventName("ResultOptionsDefaultEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsDefaultEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.OnEventName("ResultOptionsDefaultEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsDefaultEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - bus.OnEventName("ResultOptionsDefaultEvent", "forwarded", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsDefaultEvent", "forwarded", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return abxbus.NewBaseEvent("ForwardedResultEvent", nil), nil }, nil) - defaultEvent := bus.EmitEventName("ResultOptionsDefaultEvent", nil) + defaultEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsDefaultEvent", nil)) if _, err := defaultEvent.Now(); err != nil { t.Fatal(err) } @@ -244,13 +244,13 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( t.Fatalf("default result filtering mismatch: %#v", defaultValues) } - bus.OnEventName("ResultOptionsErrorEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsErrorEvent", "ok", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - bus.OnEventName("ResultOptionsErrorEvent", "boom", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsErrorEvent", "boom", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - errorEvent := bus.EmitEventName("ResultOptionsErrorEvent", nil) + errorEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsErrorEvent", nil)) if _, err := errorEvent.Now(); err != nil { t.Fatal(err) } @@ -265,10 +265,10 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( t.Fatalf("raise_if_any=false values mismatch: %#v", valuesWithoutErrors) } - bus.OnEventName("ResultOptionsEmptyEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsEmptyEvent", "nil", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) - emptyEvent := bus.EmitEventName("ResultOptionsEmptyEvent", nil) + emptyEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsEmptyEvent", nil)) if _, err := emptyEvent.Now(); err != nil { t.Fatal(err) } @@ -283,14 +283,14 @@ func TestEventResultsListDefaultsFilterEmptyValuesRaiseErrorsAndOptionsOverride( t.Fatalf("raise_if_none=false should allow empty result list, got %#v", emptyValues) } - bus.OnEventName("ResultOptionsIncludeEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsIncludeEvent", "keep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "keep", nil }, nil) - bus.OnEventName("ResultOptionsIncludeEvent", "drop", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ResultOptionsIncludeEvent", "drop", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "drop", nil }, nil) seenHandlerNames := []string{} - includeEvent := bus.EmitEventName("ResultOptionsIncludeEvent", nil) + includeEvent := bus.Emit(abxbus.NewBaseEvent("ResultOptionsIncludeEvent", nil)) if _, err := includeEvent.Now(); err != nil { t.Fatal(err) } @@ -417,13 +417,13 @@ func TestCompletionModeAllWaitsForAllHandlers(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) slowDone := false - bus.OnEventName("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) - bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) + bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) slowDone = true return "slow", nil }, nil) - e := bus.EmitEventName("Evt", nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -438,12 +438,12 @@ func TestCompletionModeFirstSerialStopsAfterFirstNonNil(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) secondCalled := false - bus.OnEventName("Evt", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - bus.OnEventName("Evt", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) + bus.On("Evt", "second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { secondCalled = true return "second", nil }, nil) - e := bus.EmitEventName("Evt", nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -471,7 +471,7 @@ func TestCompletionModeFirstParallelReturnsFastAndCancelsSlow(t *testing.T) { }) slowStarted := make(chan struct{}, 1) slowExited := make(chan struct{}, 1) - bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { slowStarted <- struct{}{} select { case <-time.After(500 * time.Millisecond): @@ -482,7 +482,7 @@ func TestCompletionModeFirstParallelReturnsFastAndCancelsSlow(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.OnEventName("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) + bus.On("Evt", "fast", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "fast", nil }, nil) event := abxbus.NewBaseEvent("Evt", nil) event.EventHandlerCompletion = abxbus.EventHandlerCompletionFirst @@ -513,11 +513,11 @@ func TestCompletionModeFirstParallelReturnsFastAndCancelsSlow(t *testing.T) { func TestWaitUntilIdleTimeoutAndRecovery(t *testing.T) { bus := abxbus.NewEventBus("IdleTimeoutBus", nil) release := make(chan struct{}) - bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { <-release return nil, nil }, nil) - _ = bus.EmitEventName("Evt", nil) + _ = bus.Emit(abxbus.NewBaseEvent("Evt", nil)) tShort := 0.01 if bus.WaitUntilIdle(&tShort) { @@ -537,20 +537,20 @@ func TestEventResetCreatesFreshPendingEventForCrossBusDispatch(t *testing.T) { seenA := []string{} seenB := []string{} - busA.OnEventName("ResetCoverageEvent", "record_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("ResetCoverageEvent", "record_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if label, ok := event.Payload["label"].(string); ok { seenA = append(seenA, label) } return "a:" + event.Payload["label"].(string), nil }, nil) - busB.OnEventName("ResetCoverageEvent", "record_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("ResetCoverageEvent", "record_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { if label, ok := event.Payload["label"].(string); ok { seenB = append(seenB, label) } return "b:" + event.Payload["label"].(string), nil }, nil) - completed := busA.EmitEventName("ResetCoverageEvent", map[string]any{"label": "hello"}) + completed := busA.Emit(abxbus.NewBaseEvent("ResetCoverageEvent", map[string]any{"label": "hello"})) if _, err := completed.Now(); err != nil { t.Fatal(err) } @@ -605,12 +605,12 @@ func TestIsIdleAndQueueEmptyStates(t *testing.T) { started := make(chan struct{}, 1) release := make(chan struct{}) - bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} <-release return nil, nil }, nil) - _ = bus.EmitEventName("Evt", nil) + _ = bus.Emit(abxbus.NewBaseEvent("Evt", nil)) select { case <-started: @@ -759,18 +759,18 @@ func assertRecordStatuses(t *testing.T, records []middlewareRecord, expected []s func TestEventBusMiddlewareReceivesPendingStartedCompletedLifecycleHooks(t *testing.T) { middleware := newRecordingMiddleware("single", nil) bus := abxbus.NewEventBus("MiddlewareBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - handler := bus.OnEventName("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler := bus.On("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) bus.Off("MiddlewareEvent", handler) - handler = bus.OnEventName("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handler = bus.On("MiddlewareEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, &abxbus.EventHandler{ ID: handler.ID, HandlerRegisteredAt: handler.HandlerRegisteredAt, }) - event := bus.EmitEventName("MiddlewareEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("MiddlewareEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -809,11 +809,11 @@ func TestEventBusMiddlewareHooksExecuteInRegistrationOrder(t *testing.T) { bus := abxbus.NewEventBus("MiddlewareOrderBus", &abxbus.EventBusOptions{ Middlewares: []abxbus.EventBusMiddleware{first, second}, }) - bus.OnEventName("MiddlewareOrderEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MiddlewareOrderEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - if _, err := bus.EmitEventName("MiddlewareOrderEvent", nil).Now(); err != nil { + if _, err := bus.Emit(abxbus.NewBaseEvent("MiddlewareOrderEvent", nil)).Now(); err != nil { t.Fatal(err) } @@ -837,7 +837,7 @@ func TestEventBusMiddlewareNoHandlerEventLifecycle(t *testing.T) { middleware := newRecordingMiddleware("single", nil) bus := abxbus.NewEventBus("MiddlewareNoHandlerBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - event := bus.EmitEventName("MiddlewareNoHandlerEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("MiddlewareNoHandlerEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -856,7 +856,7 @@ func TestEventBusMiddlewareEventLifecycleOrderingIsDeterministicPerEvent(t *test Middlewares: []abxbus.EventBusMiddleware{middleware}, MaxHistorySize: &historySize, }) - bus.OnEventName("MiddlewareDeterministicEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MiddlewareDeterministicEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(time.Millisecond) return "ok", nil }, nil) @@ -895,11 +895,11 @@ func TestEventBusMiddlewareEventLifecycleOrderingIsDeterministicPerEvent(t *test func TestEventBusMiddlewareHooksObserveHandlerErrorsWithoutErrorHookStatus(t *testing.T) { middleware := newRecordingMiddleware("errors", nil) bus := abxbus.NewEventBus("MiddlewareErrorBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - bus.OnEventName("MiddlewareErrorEvent", "failing", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MiddlewareErrorEvent", "failing", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, errors.New("boom") }, nil) - event := bus.EmitEventName("MiddlewareErrorEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("MiddlewareErrorEvent", nil)) _, err := event.EventResult() if err == nil || !strings.Contains(err.Error(), "boom") { t.Fatalf("expected handler error from event result, got %v", err) @@ -923,7 +923,7 @@ func TestEventBusMiddlewareHooksRemainMonotonicOnEventTimeout(t *testing.T) { Middlewares: []abxbus.EventBusMiddleware{middleware}, EventHandlerConcurrency: abxbus.EventHandlerConcurrencySerial, }) - bus.OnEventName("MiddlewareTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MiddlewareTimeoutEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "late", nil @@ -931,7 +931,7 @@ func TestEventBusMiddlewareHooksRemainMonotonicOnEventTimeout(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.OnEventName("MiddlewareTimeoutEvent", "pending", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MiddlewareTimeoutEvent", "pending", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "pending", nil }, nil) timeout := 0.02 @@ -964,7 +964,7 @@ func TestEventBusMiddlewareHardEventTimeoutFinalizesImmediatelyWithoutWaitingFor started := make(chan struct{}, 2) for _, handlerName := range []string{"slow_1", "slow_2"} { handlerName := handlerName - bus.OnEventName("MiddlewareHardTimeoutEvent", handlerName, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("MiddlewareHardTimeoutEvent", handlerName, func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { started <- struct{}{} time.Sleep(200 * time.Millisecond) return "late:" + handlerName, nil @@ -1019,7 +1019,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) - serialBus.OnEventName("MiddlewareSchemaEvent", "bad_schema", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + serialBus.On("MiddlewareSchemaEvent", "bad_schema", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "not-a-number", nil }, nil) schemaEvent := abxbus.NewBaseEvent("MiddlewareSchemaEvent", nil) @@ -1038,7 +1038,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli } } - serialBus.OnEventName("MiddlewareSerialTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + serialBus.On("MiddlewareSerialTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow", nil @@ -1046,7 +1046,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli return nil, ctx.Err() } }, nil) - serialBus.OnEventName("MiddlewareSerialTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + serialBus.On("MiddlewareSerialTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow-2", nil @@ -1069,7 +1069,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli t.Fatalf("serial event timeout should abort or time out a running handler explicitly, got %#v", serialErrors) } - parallelBus.OnEventName("MiddlewareParallelTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parallelBus.On("MiddlewareParallelTimeoutEvent", "slow_1", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow", nil @@ -1077,7 +1077,7 @@ func TestEventBusMiddlewareTimeoutCancelAbortAndResultSchemaTaxonomyRemainsExpli return nil, ctx.Err() } }, nil) - parallelBus.OnEventName("MiddlewareParallelTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + parallelBus.On("MiddlewareParallelTimeoutEvent", "slow_2", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(100 * time.Millisecond): return "slow-2", nil @@ -1125,15 +1125,15 @@ func TestEventBusMiddlewareHooksArePerBusOnForwardedEvents(t *testing.T) { middlewareB := newRecordingMiddleware("b", nil) busA := abxbus.NewEventBus("MiddlewareForwardA", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middlewareA}}) busB := abxbus.NewEventBus("MiddlewareForwardB", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middlewareB}}) - handlerA := busA.OnEventName("MiddlewareForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerA := busA.On("MiddlewareForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busB.Emit(event) return "forwarded", nil }, nil) - handlerB := busB.OnEventName("MiddlewareForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + handlerB := busB.On("MiddlewareForwardEvent", "target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "target", nil }, nil) - if _, err := busA.EmitEventName("MiddlewareForwardEvent", nil).Now(); err != nil { + if _, err := busA.Emit(abxbus.NewBaseEvent("MiddlewareForwardEvent", nil)).Now(); err != nil { t.Fatal(err) } @@ -1150,14 +1150,14 @@ func TestEventBusMiddlewareHooksArePerBusOnForwardedEvents(t *testing.T) { func TestEventBusMiddlewareHooksCoverStringAndWildcardPatterns(t *testing.T) { middleware := newRecordingMiddleware("patterns", nil) bus := abxbus.NewEventBus("MiddlewarePatternBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - stringHandler := bus.OnEventName("MiddlewarePatternEvent", "string", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + stringHandler := bus.On("MiddlewarePatternEvent", "string", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "string:" + event.EventType, nil }, nil) wildcardHandler := bus.OnEventName("*", "wildcard", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "wildcard:" + event.EventType, nil }, nil) - event := bus.EmitEventName("MiddlewarePatternEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("MiddlewarePatternEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1232,18 +1232,18 @@ func TestSameNameEventBusesKeepIndependentIDsHandlersAndHistory(t *testing.T) { t.Fatal("same-name buses should still have distinct ids") } - first.OnEventName("NameConflictEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + first.On("NameConflictEvent", "first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "first", nil }, nil) - second.OnEventName("NameConflictEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + second.On("NameConflictEvent", "second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "second", nil }, nil) - firstResult, err := first.EmitEventName("NameConflictEvent", nil).EventResult() + firstResult, err := first.Emit(abxbus.NewBaseEvent("NameConflictEvent", nil)).EventResult() if err != nil { t.Fatal(err) } - secondResult, err := second.EmitEventName("NameConflictEvent", nil).EventResult() + secondResult, err := second.Emit(abxbus.NewBaseEvent("NameConflictEvent", nil)).EventResult() if err != nil { t.Fatal(err) } @@ -1259,12 +1259,12 @@ func TestSameNameEventBusesKeepIndependentIDsHandlersAndHistory(t *testing.T) { func TestDestroyClearFalsePreservesHandlersAndHistoryResolvesWaitersAndIsTerminal(t *testing.T) { bus := abxbus.NewEventBus("DestroyClearFalseTerminalBus", nil) var calls atomic.Int32 - bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls.Add(1) return "ok", nil }, nil) - e := bus.EmitEventName("Evt", nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := e.Now(); err != nil { t.Fatal(err) } @@ -1330,12 +1330,16 @@ func TestDestroyClearFalsePreservesHandlersAndHistoryResolvesWaitersAndIsTermina }() fn() } - assertDestroyedPanic("Emit", func() { bus.EmitEventName("Evt", nil) }) + assertDestroyedPanic("Emit", func() { bus.Emit(abxbus.NewBaseEvent("Evt", nil)) }) assertDestroyedPanic("On", func() { - bus.OnEventName("Evt", "again", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "again", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) }) + assertDestroyedPanic("On", func() { + type ClearFalseDestroyedEvent struct{} + bus.On(func(payload ClearFalseDestroyedEvent) {}) + }) if _, err := bus.FindEventName("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { t.Fatalf("Find should reject with ErrEventBusDestroyed, got %v", err) } @@ -1348,7 +1352,7 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { lateEmitRejected := make(chan bool, 1) var startOnce sync.Once - bus.OnEventName("SlowEvt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("SlowEvt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { startOnce.Do(func() { close(started) }) <-release rejected := false @@ -1360,13 +1364,13 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { } } }() - bus.EmitEventName("LateEvt", nil) + bus.Emit(abxbus.NewBaseEvent("LateEvt", nil)) }() lateEmitRejected <- rejected return "slow", nil }, nil) - bus.EmitEventName("SlowEvt", nil) + bus.Emit(abxbus.NewBaseEvent("SlowEvt", nil)) select { case <-started: case <-time.After(2 * time.Second): @@ -1392,7 +1396,7 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { t.Fatalf("expected destroyed error panic, got %#v", recovered) } }() - bus.EmitEventName("OutsideEvt", nil) + bus.Emit(abxbus.NewBaseEvent("OutsideEvt", nil)) }() close(release) @@ -1409,10 +1413,10 @@ func TestDestroyIsImmediateAndRejectsLateHandlerEmits(t *testing.T) { func TestDestroyDefaultClearIsTerminalAndFreesBusState(t *testing.T) { bus := abxbus.NewEventBus("TerminalDestroyBus", nil) - bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.EmitEventName("Evt", nil) + event := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1479,9 +1483,13 @@ func TestDestroyDefaultClearIsTerminalAndFreesBusState(t *testing.T) { }() fn() } - assertDestroyedPanic("Emit", func() { bus.EmitEventName("Evt", nil) }) + assertDestroyedPanic("Emit", func() { bus.Emit(abxbus.NewBaseEvent("Evt", nil)) }) + assertDestroyedPanic("On", func() { + bus.On("Evt", "new", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) + }) assertDestroyedPanic("On", func() { - bus.OnEventName("Evt", "new", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, nil }, nil) + type TerminalDestroyedEvent struct{} + bus.On(func(payload TerminalDestroyedEvent) {}) }) if _, err := bus.FindEventName("Evt", nil, nil); !errors.Is(err, abxbus.ErrEventBusDestroyed) { @@ -1502,13 +1510,13 @@ func TestDestroyingOneBusDoesNotBreakSharedHandlersOrForwardTargets(t *testing.T seen.Add(1) return "shared", nil } - source.OnEventName("SharedDestroyEvent", "shared_source", shared, nil) + source.On("SharedDestroyEvent", "shared_source", shared, nil) source.OnEventName("*", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return target.Emit(event), nil }, nil) - target.OnEventName("SharedDestroyEvent", "shared_target", shared, nil) + target.On("SharedDestroyEvent", "shared_target", shared, nil) - forwarded := source.EmitEventName("SharedDestroyEvent", nil) + forwarded := source.Emit(abxbus.NewBaseEvent("SharedDestroyEvent", nil)) if _, err := forwarded.Now(); err != nil { t.Fatal(err) } @@ -1518,7 +1526,7 @@ func TestDestroyingOneBusDoesNotBreakSharedHandlersOrForwardTargets(t *testing.T source.Destroy() - direct := target.EmitEventName("SharedDestroyEvent", nil) + direct := target.Emit(abxbus.NewBaseEvent("SharedDestroyEvent", nil)) completedDirect, err := direct.Now() if err != nil { t.Fatalf("target should still process after source destroy: %v", err) @@ -1631,11 +1639,11 @@ func TestOtelTracingMiddlewareCreatesEventAndHandlerSpans(t *testing.T) { }, }) bus := abxbus.NewEventBus("OtelBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - bus.OnEventName("OtelEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("OtelEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.EmitEventName("OtelEvent", map[string]any{"session_id": "event-session-456", "value": "x"}) + event := bus.Emit(abxbus.NewBaseEvent("OtelEvent", map[string]any{"session_id": "event-session-456", "value": "x"})) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -1683,7 +1691,7 @@ func TestOtelTracingMiddlewareNamesEventAndHandlerSpansForDisplay(t *testing.T) }) bus := abxbus.NewEventBus("StagehandExtensionBackground", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) t.Cleanup(bus.Destroy) - bus.OnEventName("CDPConnect", "DebuggerClient.on_CDPConnect", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("CDPConnect", "DebuggerClient.on_CDPConnect", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "connected", nil }, nil) @@ -1707,18 +1715,18 @@ func TestOtelTracingMiddlewareParentsChildEventToEmittingHandlerSpan(t *testing. Tracer: provider.Tracer("abxbus-test"), }) bus := abxbus.NewEventBus("OtelParentBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) - bus.OnEventName("ParentOtelEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { - child := event.EmitEventName("ChildOtelEvent", nil) + bus.On("ParentOtelEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + child := event.Emit(abxbus.NewBaseEvent("ChildOtelEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } return "parent", nil }, nil) - bus.OnEventName("ChildOtelEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ChildOtelEvent", "child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "child", nil }, nil) - parent := bus.EmitEventName("ParentOtelEvent", nil) + parent := bus.Emit(abxbus.NewBaseEvent("ParentOtelEvent", nil)) if _, err := parent.Now(); err != nil { t.Fatal(err) } @@ -1760,7 +1768,7 @@ func TestOtelTracingMiddlewareWaitsUntilTopLevelEventCompletionBeforeEndingSpans started := make(chan struct{}) release := make(chan struct{}) - bus.OnEventName("OtelRootStartEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("OtelRootStartEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { close(started) select { case <-release: @@ -1811,11 +1819,11 @@ func TestOtelTracingMiddlewareRecordsHandlerErrors(t *testing.T) { }) bus := abxbus.NewEventBus("OtelErrorBus", &abxbus.EventBusOptions{Middlewares: []abxbus.EventBusMiddleware{middleware}}) handlerErr := errors.New("handler failed") - bus.OnEventName("OtelErrorEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("OtelErrorEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return nil, handlerErr }, nil) - event := bus.EmitEventName("OtelErrorEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("OtelErrorEvent", nil)) if _, err := event.Wait(); err != nil { t.Fatal(err) } diff --git a/abxbus-go/tests/eventbus_timeout_test.go b/abxbus-go/tests/eventbus_timeout_test.go index 3dae0bd6..4fd2b763 100644 --- a/abxbus-go/tests/eventbus_timeout_test.go +++ b/abxbus-go/tests/eventbus_timeout_test.go @@ -13,7 +13,7 @@ func TestTimeoutPrecedenceEventOverBus(t *testing.T) { busTimeout := 5.0 eventTimeout := 0.01 bus := abxbus.NewEventBus("TimeoutBus", &abxbus.EventBusOptions{EventTimeout: &busTimeout}) - bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, nil) @@ -37,7 +37,7 @@ func TestTimeoutPrecedenceEventOverBus(t *testing.T) { func TestZeroTimeoutAllowsSlowHandler(t *testing.T) { busTimeout := 0.01 bus := abxbus.NewEventBus("NoTimeoutBus", &abxbus.EventBusOptions{EventTimeout: &busTimeout}) - bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(20 * time.Millisecond) return "ok", nil }, nil) @@ -61,11 +61,11 @@ func TestProcessingTimeTimeoutDefaultsResolveAtExecutionTime(t *testing.T) { }) t.Cleanup(bus.Destroy) - bus.OnEventName("TimeoutEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) - event := bus.EmitEventName("TimeoutEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("TimeoutEvent", nil)) if event.EventTimeout != nil { t.Fatalf("expected nil event_timeout, got %#v", event.EventTimeout) } @@ -106,7 +106,7 @@ func TestEventTimeoutNilUsesBusDefaultTimeoutAtExecution(t *testing.T) { bus := abxbus.NewEventBus("TimeoutNilUsesBusDefault", &abxbus.EventBusOptions{EventTimeout: &busTimeout}) t.Cleanup(bus.Destroy) - bus.OnEventName("TimeoutDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutDefaultsEvent", "slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(20 * time.Millisecond): return "slow", nil @@ -115,7 +115,7 @@ func TestEventTimeoutNilUsesBusDefaultTimeoutAtExecution(t *testing.T) { } }, nil) - event := bus.EmitEventName("TimeoutDefaultsEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("TimeoutDefaultsEvent", nil)) if _, err := event.Now(); err != nil { t.Fatal(err) } @@ -139,7 +139,7 @@ func TestHandlerTimeoutResolutionMatchesPrecedence(t *testing.T) { EventHandlerCompletion: abxbus.EventHandlerCompletionAll, EventHandlerDetectFilePaths: &detectPaths, }) - bus.OnEventName("TimeoutDefaultsEvent", "default_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutDefaultsEvent", "default_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { sleepFor := 80 * time.Millisecond if e.Payload["scenario"] == "event-cap" { sleepFor = 150 * time.Millisecond @@ -151,7 +151,7 @@ func TestHandlerTimeoutResolutionMatchesPrecedence(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.OnEventName("TimeoutDefaultsEvent", "overridden_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutDefaultsEvent", "overridden_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { sleepFor := 80 * time.Millisecond if e.Payload["scenario"] == "event-cap" { sleepFor = 150 * time.Millisecond @@ -215,13 +215,13 @@ func TestHandlerTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { lateAttempt := make(chan struct{}, 1) lateHandlerRan := false - bus.OnEventName("TimeoutIgnoresLateHandlerEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutIgnoresLateHandlerEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(40 * time.Millisecond) lateAttempt <- struct{}{} - event.EmitEventName("LateAfterTimeoutEvent", nil) + event.Emit(abxbus.NewBaseEvent("LateAfterTimeoutEvent", nil)) return "late success", nil }, &abxbus.EventHandler{HandlerTimeout: &handlerTimeout}) - bus.OnEventName("LateAfterTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("LateAfterTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { lateHandlerRan = true return "late child", nil }, nil) @@ -269,13 +269,13 @@ func TestEventTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { lateAttempt := make(chan struct{}, 1) lateHandlerRan := false - bus.OnEventName("TimeoutIgnoresLateEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutIgnoresLateEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(40 * time.Millisecond) lateAttempt <- struct{}{} - event.EmitEventName("LateAfterEventTimeoutEvent", nil) + event.Emit(abxbus.NewBaseEvent("LateAfterEventTimeoutEvent", nil)) return "late success", nil }, nil) - bus.OnEventName("LateAfterEventTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("LateAfterEventTimeoutEvent", "late_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { lateHandlerRan = true return "late child", nil }, nil) @@ -317,7 +317,7 @@ func TestEventTimeoutIgnoresLateHandlerResultAndLateEmits(t *testing.T) { func TestEventHandlerDetectFilePathsToggle(t *testing.T) { detectPaths := false bus := abxbus.NewEventBus("NoDetectPathsBus", &abxbus.EventBusOptions{EventHandlerDetectFilePaths: &detectPaths}) - entry := bus.OnEventName("TimeoutDefaultsEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + entry := bus.On("TimeoutDefaultsEvent", "handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "ok", nil }, nil) if entry.HandlerFilePath != nil { @@ -346,7 +346,7 @@ func TestHandlerSlowWarningUsesEventHandlerSlowTimeout(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) mu.Lock() messages = append(messages, "slow warning child handler finishing") @@ -395,7 +395,7 @@ func TestEventSlowWarningUsesEventSlowTimeout(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) mu.Lock() messages = append(messages, "slow warning child handler finishing") @@ -441,7 +441,7 @@ func TestSlowHandlerAndSlowEventWarningsCanBothFire(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "ok", nil }, nil) @@ -485,7 +485,7 @@ func TestZeroSlowWarningThresholdsDisableEventAndHandlerSlowWarnings(t *testing. } defer func() { abxbus.SlowWarningLogger = originalLogger }() - bus.OnEventName("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutDefaultsEvent", "slow_handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) mu.Lock() messages = append(messages, "slow warning child handler finishing") @@ -493,7 +493,7 @@ func TestZeroSlowWarningThresholdsDisableEventAndHandlerSlowWarnings(t *testing. return "ok", nil }, nil) - if _, err := bus.EmitEventName("TimeoutDefaultsEvent", nil).Now(); err != nil { + if _, err := bus.Emit(abxbus.NewBaseEvent("TimeoutDefaultsEvent", nil)).Now(); err != nil { t.Fatal(err) } mu.Lock() @@ -515,10 +515,10 @@ func TestForwardedEventTimeoutAbortsTargetBusHandler(t *testing.T) { t.Cleanup(busA.Destroy) t.Cleanup(busB.Destroy) - busA.OnEventName("TimeoutForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("TimeoutForwardEvent", "forward", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return busB.Emit(event), nil }, nil) - busB.OnEventName("TimeoutForwardEvent", "slow_target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("TimeoutForwardEvent", "slow_target", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(50 * time.Millisecond): return "slow", nil @@ -563,7 +563,7 @@ func TestQueueJumpAwaitedChildTimeoutAbortsAcrossBuses(t *testing.T) { t.Cleanup(busB.Destroy) var childRef *abxbus.BaseEvent - busB.OnEventName("TimeoutChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("TimeoutChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(50 * time.Millisecond): return "slow", nil @@ -571,9 +571,9 @@ func TestQueueJumpAwaitedChildTimeoutAbortsAcrossBuses(t *testing.T) { return nil, ctx.Err() } }, nil) - busA.OnEventName("TimeoutParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("TimeoutParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childTimeout := 0.01 - child := event.EmitEventName("TimeoutChildEvent", nil) + child := event.Emit(abxbus.NewBaseEvent("TimeoutChildEvent", nil)) child.EventTimeout = &childTimeout busB.Emit(child) childRef = child @@ -621,7 +621,7 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { busBTailRuns := 0 var childRef *abxbus.BaseEvent - busA.OnEventName("TimeoutRecoveryParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("TimeoutRecoveryParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childTimeout := 0.01 childEvent := abxbus.NewBaseEvent("TimeoutRecoveryChildEvent", nil) childEvent.EventTimeout = &childTimeout @@ -632,14 +632,14 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { } return "parent_done", nil }, nil) - busA.OnEventName("TimeoutRecoveryTailEvent", "tail_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busA.On("TimeoutRecoveryTailEvent", "tail_a", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busATailRuns++ return "tail_a", nil }, nil) busA.OnEventName("*", "forward_to_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { return busB.Emit(event), nil }, nil) - busB.OnEventName("TimeoutRecoveryChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("TimeoutRecoveryChildEvent", "slow_child", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(50 * time.Millisecond): return "child_done", nil @@ -647,7 +647,7 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { return nil, ctx.Err() } }, nil) - busB.OnEventName("TimeoutRecoveryTailEvent", "tail_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + busB.On("TimeoutRecoveryTailEvent", "tail_b", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { busBTailRuns++ return "tail_b", nil }, nil) @@ -680,7 +680,7 @@ func TestForwardedTimeoutPathDoesNotStallFollowupEvents(t *testing.T) { t.Fatalf("expected child timeout/abort result, got %#v", childRef.EventResults) } - tail := busA.EmitEventName("TimeoutRecoveryTailEvent", nil) + tail := busA.Emit(abxbus.NewBaseEvent("TimeoutRecoveryTailEvent", nil)) if _, err := tail.Now(); err != nil { t.Fatal(err) } @@ -704,17 +704,17 @@ func TestParentTimeoutDoesNotCancelUnawaitedChildHandlerResultsUnderSerialHandle t.Cleanup(bus.Destroy) childRuns := 0 - bus.OnEventName("TimeoutCancelChildEvent", "child_first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCancelChildEvent", "child_first", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childRuns++ time.Sleep(30 * time.Millisecond) return "first", nil }, nil) - bus.OnEventName("TimeoutCancelChildEvent", "child_second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCancelChildEvent", "child_second", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childRuns++ time.Sleep(10 * time.Millisecond) return "second", nil }, nil) - bus.OnEventName("TimeoutCancelParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCancelParentEvent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childTimeout := 0.2 child := abxbus.NewBaseEvent("TimeoutCancelChildEvent", nil) child.EventTimeout = &childTimeout @@ -771,21 +771,21 @@ func TestMultiLevelTimeoutCascadeWithMixedCancellations(t *testing.T) { immediateGrandchildRuns := 0 queuedGrandchildRuns := 0 - bus.OnEventName("TimeoutCascadeQueuedChild", "queued_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeQueuedChild", "queued_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedChildRuns++ time.Sleep(5 * time.Millisecond) return "queued_fast", nil }, nil) - bus.OnEventName("TimeoutCascadeQueuedChild", "queued_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeQueuedChild", "queued_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedChildRuns++ time.Sleep(50 * time.Millisecond) return "queued_slow", nil }, nil) - bus.OnEventName("TimeoutCascadeAwaitedChild", "awaited_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeAwaitedChild", "awaited_child_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(5 * time.Millisecond) return "awaited_fast", nil }, nil) - bus.OnEventName("TimeoutCascadeAwaitedChild", "awaited_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeAwaitedChild", "awaited_child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedTimeout := 0.2 queuedGrandchild = abxbus.NewBaseEvent("TimeoutCascadeQueuedGrandchild", nil) queuedGrandchild.EventTimeout = &queuedTimeout @@ -805,7 +805,7 @@ func TestMultiLevelTimeoutCascadeWithMixedCancellations(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.OnEventName("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { immediateGrandchildRuns++ select { case <-time.After(50 * time.Millisecond): @@ -814,22 +814,22 @@ func TestMultiLevelTimeoutCascadeWithMixedCancellations(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.OnEventName("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeImmediateGrandchild", "immediate_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { immediateGrandchildRuns++ time.Sleep(10 * time.Millisecond) return "immediate_grandchild_fast", nil }, nil) - bus.OnEventName("TimeoutCascadeQueuedGrandchild", "queued_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeQueuedGrandchild", "queued_grandchild_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedGrandchildRuns++ time.Sleep(50 * time.Millisecond) return "queued_grandchild_slow", nil }, nil) - bus.OnEventName("TimeoutCascadeQueuedGrandchild", "queued_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeQueuedGrandchild", "queued_grandchild_fast", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedGrandchildRuns++ time.Sleep(10 * time.Millisecond) return "queued_grandchild_fast", nil }, nil) - bus.OnEventName("TimeoutCascadeTop", "top", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutCascadeTop", "top", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { queuedTimeout := 0.2 queuedChild = abxbus.NewBaseEvent("TimeoutCascadeQueuedChild", nil) queuedChild.EventTimeout = &queuedTimeout @@ -908,11 +908,11 @@ func TestUnawaitedDescendantPreservesLineageAndIsNotCancelledByAncestorTimeout(t var innerRef *abxbus.BaseEvent var deepRef *abxbus.BaseEvent - bus.OnEventName("ErrorChainDeep", "deep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ErrorChainDeep", "deep", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(200 * time.Millisecond) return "deep_done", nil }, nil) - bus.OnEventName("ErrorChainInner", "inner", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ErrorChainInner", "inner", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { deepTimeout := 0.5 deepRef = abxbus.NewBaseEvent("ErrorChainDeep", nil) deepRef.EventTimeout = &deepTimeout @@ -924,7 +924,7 @@ func TestUnawaitedDescendantPreservesLineageAndIsNotCancelledByAncestorTimeout(t return nil, ctx.Err() } }, nil) - bus.OnEventName("ErrorChainOuter", "outer", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("ErrorChainOuter", "outer", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { innerTimeout := 0.04 innerRef = abxbus.NewBaseEvent("ErrorChainInner", nil) innerRef.EventTimeout = &innerTimeout @@ -989,12 +989,12 @@ func TestParentTimeoutDoesNotCancelUnawaitedChildrenThatHaveNoTimeoutOfTheirOwn( var childRef *abxbus.BaseEvent childHandlerRan := false - bus.OnEventName("TimeoutBoundaryChild", "child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutBoundaryChild", "child_slow", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childHandlerRan = true time.Sleep(80 * time.Millisecond) return "child_done", nil }, nil) - bus.OnEventName("TimeoutBoundaryParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("TimeoutBoundaryParent", "parent", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { childRef = abxbus.NewBaseEvent("TimeoutBoundaryChild", nil) childRef.EventTimeout = nil childRef = event.Emit(childRef) @@ -1103,12 +1103,12 @@ func TestSlowEventAndHandlerWarnings(t *testing.T) { } defer func() { abxbus.SlowWarningLogger = original }() - bus.OnEventName("Evt", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow_handler", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { time.Sleep(30 * time.Millisecond) return "ok", nil }, nil) - e := bus.EmitEventName("Evt", nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) _, err := e.Now() if err != nil { t.Fatal(err) @@ -1145,7 +1145,7 @@ func TestEventTimeoutMarksAbortedAndCancelledHandlers(t *testing.T) { EventHandlerSlowTimeout: &no_timeout, EventSlowTimeout: &no_timeout, }) - bus.OnEventName("Evt", "slow_first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow_first", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(250 * time.Millisecond): return "late", nil @@ -1153,7 +1153,7 @@ func TestEventTimeoutMarksAbortedAndCancelledHandlers(t *testing.T) { return nil, ctx.Err() } }, nil) - bus.OnEventName("Evt", "pending_second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "pending_second", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { return "never", nil }, nil) @@ -1193,7 +1193,7 @@ func TestHandlerTimeoutUsesTimedOutErrorMessage(t *testing.T) { bus_timeout := 5.0 bus := abxbus.NewEventBus("HandlerTimeoutMessageBus", &abxbus.EventBusOptions{EventTimeout: &bus_timeout}) overrides := &abxbus.EventHandler{HandlerTimeout: &handler_timeout} - bus.OnEventName("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "slow", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { select { case <-time.After(200 * time.Millisecond): return "late", nil @@ -1201,7 +1201,7 @@ func TestHandlerTimeoutUsesTimedOutErrorMessage(t *testing.T) { return nil, ctx.Err() } }, overrides) - e := bus.EmitEventName("Evt", nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) _, err := e.EventResult() if err == nil { t.Fatal("expected timeout error") diff --git a/abxbus-go/tests/lock_manager_test.go b/abxbus-go/tests/lock_manager_test.go index 8862d2ff..25fd6079 100644 --- a/abxbus-go/tests/lock_manager_test.go +++ b/abxbus-go/tests/lock_manager_test.go @@ -19,7 +19,7 @@ func lockManagerUpdateMax(maxActive *atomic.Int32, value int32) { } func registerActiveLockManagerHandler(bus *abxbus.EventBus, eventType string, handlerName string, active *atomic.Int32, maxActive *atomic.Int32) { - bus.OnEventName(eventType, handlerName, func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On(eventType, handlerName, func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { nowActive := active.Add(1) lockManagerUpdateMax(maxActive, nowActive) time.Sleep(20 * time.Millisecond) @@ -120,7 +120,7 @@ func TestWaitUntilIdleBehavesCorrectly(t *testing.T) { bus := abxbus.NewEventBus("IdleBus", nil) defer bus.Destroy() var calls atomic.Int32 - bus.OnEventName("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("Evt", "h", func(e *abxbus.BaseEvent, ctx context.Context) (any, error) { calls.Add(1) return "ok", nil }, nil) @@ -130,7 +130,7 @@ func TestWaitUntilIdleBehavesCorrectly(t *testing.T) { t.Fatal("bus should be idle before any events") } - e := bus.EmitEventName("Evt", nil) + e := bus.Emit(abxbus.NewBaseEvent("Evt", nil)) if !bus.WaitUntilIdle(&short) { t.Fatal("bus should become idle after event completion") } @@ -163,8 +163,8 @@ func TestLockManagerGetLockForEventModes(t *testing.T) { EventHandlerConcurrency: abxbus.EventHandlerConcurrencyParallel, }) registerActiveLockManagerHandler(busSerial, "LockModesEvent", "handler", &active, &maxActive) - busSerial.EmitEventName("LockModesEvent", nil) - busSerial.EmitEventName("LockModesEvent", nil) + busSerial.Emit(abxbus.NewBaseEvent("LockModesEvent", nil)) + busSerial.Emit(abxbus.NewBaseEvent("LockModesEvent", nil)) if !busSerial.WaitUntilIdle(&timeout) { t.Fatal("bus-serial bus did not become idle") } @@ -235,7 +235,7 @@ func TestLockManagerGetLockForEventHandlerModes(t *testing.T) { }) registerActiveLockManagerHandler(serialBus, "LockHandlerModesEvent", "handler_a", &active, &maxActive) registerActiveLockManagerHandler(serialBus, "LockHandlerModesEvent", "handler_b", &active, &maxActive) - serialBus.EmitEventName("LockHandlerModesEvent", nil) + serialBus.Emit(abxbus.NewBaseEvent("LockHandlerModesEvent", nil)) if !serialBus.WaitUntilIdle(&timeout) { t.Fatal("serial handler bus did not become idle") } @@ -298,8 +298,8 @@ func TestRunWithEventLockAndHandlerLockRespectParallelBypass(t *testing.T) { }) registerActiveLockManagerHandler(serialBus, "SerialAcquireEvent", "handler_a", &active, &maxActive) registerActiveLockManagerHandler(serialBus, "SerialAcquireEvent", "handler_b", &active, &maxActive) - serialBus.EmitEventName("SerialAcquireEvent", nil) - serialBus.EmitEventName("SerialAcquireEvent", nil) + serialBus.Emit(abxbus.NewBaseEvent("SerialAcquireEvent", nil)) + serialBus.Emit(abxbus.NewBaseEvent("SerialAcquireEvent", nil)) if !serialBus.WaitUntilIdle(&timeout) { t.Fatal("serial acquire bus did not become idle") } diff --git a/docs/api/baseevent.mdx b/docs/api/baseevent.mdx index 0aadc803..acdcddea 100644 --- a/docs/api/baseevent.mdx +++ b/docs/api/baseevent.mdx @@ -40,18 +40,16 @@ const FooCreateEvent = BaseEvent.extend('FooCreateEvent', { ```go -type FooPayload struct { +type FooCreateEvent struct { ID *string `json:"id,omitempty"` Name string `json:"name"` Age int `json:"age"` } -type FooResult string - -event, err := abxbus.NewEvent[FooPayload]("FooCreateEvent", FooPayload{ +event, err := abxbus.Event(FooCreateEvent{ Name: "Ada", Age: 37, -}, abxbus.ResultType[FooResult]()) +}) ``` @@ -149,7 +147,7 @@ const value = await completed.eventResult() ```go type MyEvent struct{} -pending := bus.Emit(abxbus.MustNewEvent("MyEvent", MyEvent{})) +pending := bus.Emit(MyEvent{}) completed, err := pending.Now() if err != nil { return err diff --git a/docs/api/eventbus.mdx b/docs/api/eventbus.mdx index c4a51d8f..33de2688 100644 --- a/docs/api/eventbus.mdx +++ b/docs/api/eventbus.mdx @@ -154,10 +154,10 @@ bus.on('*', wildcardHandler) ```go -bus.OnEventName("UserEvent", "handler", handler, nil) +bus.On("UserEvent", "handler", handler, nil) bus.OnEventName("*", "wildcard_handler", wildcardHandler, nil) timeout := 5.0 -bus.OnEventName("UserEvent", "custom", handler, &abxbus.EventHandler{ +bus.On("UserEvent", "custom", handler, &abxbus.EventHandler{ HandlerTimeout: &timeout, }) ``` @@ -220,7 +220,7 @@ bus.off('*') ```go -handler := bus.OnEventName("UserEvent", "handler", onUserEvent, nil) +handler := bus.On("UserEvent", "handler", onUserEvent, nil) bus.Off("UserEvent", handler) bus.Off("UserEvent", handler.ID) bus.Off("*", nil) @@ -266,7 +266,11 @@ const result = await event.now({ first_result: true }).eventResult() ```go -event := bus.EmitEventName("MyEvent", map[string]any{"data": "x"}) +type MyEvent struct { + Data string `json:"data"` +} + +event := bus.Emit(MyEvent{Data: "x"}) result, err := event.EventResult() if err != nil { return err @@ -597,7 +601,10 @@ await bus.destroy({ clear: true }) ```go type ResumeTickEvent struct{} -resumeTick := abxbus.MustNewEvent("ResumeTickEvent", ResumeTickEvent{}) +resumeTick, err := abxbus.Event(ResumeTickEvent{}) +if err != nil { + panic(err) +} // 1) Serialize full bus state payload, err := bus.ToJSON() @@ -618,9 +625,9 @@ fmt.Println(string(payload)) bus, err = abxbus.EventBusFromJSON(payload) // 3) Re-link runtime callables by handler id -bus.OnEventName("UserCreatedEvent", "onUserCreated", onUserCreated, bus.Handlers["018f..."]) -bus.OnEventName("UserDeletedEvent", "onUserDeleted", onUserDeleted, bus.Handlers["018g..."]) -bus.OnEventName("UserUpdatedEvent", "onUserUpdated", onUserUpdated, bus.Handlers["018h..."]) +bus.On("UserCreatedEvent", "onUserCreated", onUserCreated, bus.Handlers["018f..."]) +bus.On("UserDeletedEvent", "onUserDeleted", onUserDeleted, bus.Handlers["018g..."]) +bus.On("UserUpdatedEvent", "onUserUpdated", onUserUpdated, bus.Handlers["018h..."]) // 4) Resume processing bus.Emit(resumeTick) diff --git a/docs/api/eventhandler.mdx b/docs/api/eventhandler.mdx index ba33d593..8903aab7 100644 --- a/docs/api/eventhandler.mdx +++ b/docs/api/eventhandler.mdx @@ -40,7 +40,10 @@ bus.off(MyEvent, entry) ```go -entry := bus.OnEventName("MyEvent", "handler", handler, nil) +type MyEvent struct{} + +handler := func(event MyEvent) {} +entry := bus.On(handler) bus.Off("MyEvent", entry) ``` diff --git a/docs/concurrency/backpressure.mdx b/docs/concurrency/backpressure.mdx index b9b05013..6a05bc4e 100644 --- a/docs/concurrency/backpressure.mdx +++ b/docs/concurrency/backpressure.mdx @@ -216,7 +216,7 @@ println!("pending_event_queue={pending_count} event_history={history_count}"); ```go -event := bus.EmitEventName("MyEvent", nil) +event := bus.Emit(abxbus.NewBaseEvent("MyEvent", nil)) var state struct { PendingEventQueue []string `json:"pending_event_queue"` diff --git a/docs/concurrency/events-bus-serial.mdx b/docs/concurrency/events-bus-serial.mdx index 4d963108..05438076 100644 --- a/docs/concurrency/events-bus-serial.mdx +++ b/docs/concurrency/events-bus-serial.mdx @@ -155,12 +155,12 @@ func main() { } } - busA.OnEventName("WorkEvent", "handler_a", handler(&startsA), nil) - busB.OnEventName("WorkEvent", "handler_b", handler(&startsB), nil) + busA.On("WorkEvent", "handler_a", handler(&startsA), nil) + busB.On("WorkEvent", "handler_b", handler(&startsB), nil) for i := 0; i < 4; i++ { - busA.EmitEventName("WorkEvent", map[string]any{"order": i, "source": "a"}) - busB.EmitEventName("WorkEvent", map[string]any{"order": i, "source": "b"}) + busA.Emit(abxbus.NewBaseEvent("WorkEvent", map[string]any{"order": i, "source": "a"})) + busB.Emit(abxbus.NewBaseEvent("WorkEvent", map[string]any{"order": i, "source": "b"})) } busA.WaitUntilIdle(nil) diff --git a/docs/concurrency/events-global-serial.mdx b/docs/concurrency/events-global-serial.mdx index 12f8f847..8ed50cdd 100644 --- a/docs/concurrency/events-global-serial.mdx +++ b/docs/concurrency/events-global-serial.mdx @@ -142,12 +142,12 @@ func main() { return nil, nil } - busA.OnEventName("SerialEvent", "handler", handler, nil) - busB.OnEventName("SerialEvent", "handler", handler, nil) + busA.On("SerialEvent", "handler", handler, nil) + busB.On("SerialEvent", "handler", handler, nil) for i := 0; i < 3; i++ { - busA.EmitEventName("SerialEvent", map[string]any{"order": i, "source": "a"}) - busB.EmitEventName("SerialEvent", map[string]any{"order": i, "source": "b"}) + busA.Emit(abxbus.NewBaseEvent("SerialEvent", map[string]any{"order": i, "source": "a"})) + busB.Emit(abxbus.NewBaseEvent("SerialEvent", map[string]any{"order": i, "source": "b"})) } busA.WaitUntilIdle(nil) diff --git a/docs/concurrency/events-parallel.mdx b/docs/concurrency/events-parallel.mdx index 38c42c36..cc61a2ea 100644 --- a/docs/concurrency/events-parallel.mdx +++ b/docs/concurrency/events-parallel.mdx @@ -117,7 +117,7 @@ func main() { maxInFlight := 0 release := make(chan struct{}) - bus.OnEventName("ParallelEvent", "handler", func(event *abxbus.BaseEvent) (any, error) { + bus.On("ParallelEvent", "handler", func(event *abxbus.BaseEvent) (any, error) { mu.Lock() inFlight++ if inFlight > maxInFlight { @@ -134,8 +134,8 @@ func main() { return nil, nil }, nil) - bus.EmitEventName("ParallelEvent", map[string]any{"order": 0}) - bus.EmitEventName("ParallelEvent", map[string]any{"order": 1}) + bus.Emit(abxbus.NewBaseEvent("ParallelEvent", map[string]any{"order": 0})) + bus.Emit(abxbus.NewBaseEvent("ParallelEvent", map[string]any{"order": 1})) time.Sleep(10 * time.Millisecond) close(release) diff --git a/docs/concurrency/handler-completion-all.mdx b/docs/concurrency/handler-completion-all.mdx index 188cc3d1..8da7e233 100644 --- a/docs/concurrency/handler-completion-all.mdx +++ b/docs/concurrency/handler-completion-all.mdx @@ -112,7 +112,7 @@ func main() { var mu sync.Mutex seen := map[string]bool{} - bus.OnEventName("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.On("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { time.Sleep(10 * time.Millisecond) mu.Lock() seen["fast"] = true @@ -120,7 +120,7 @@ func main() { return "fast", nil }, nil) - bus.OnEventName("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.On("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { time.Sleep(50 * time.Millisecond) mu.Lock() seen["slow"] = true @@ -128,7 +128,7 @@ func main() { return "slow", nil }, nil) - event := bus.EmitEventName("CompletionEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("CompletionEvent", nil)) if _, err := event.Now(); err != nil { panic(err) } diff --git a/docs/concurrency/handler-completion-first.mdx b/docs/concurrency/handler-completion-first.mdx index 2eab8bc7..428d0411 100644 --- a/docs/concurrency/handler-completion-first.mdx +++ b/docs/concurrency/handler-completion-first.mdx @@ -117,19 +117,19 @@ func main() { slowStarted := make(chan struct{}, 1) slowCompleted := make(chan struct{}, 1) - bus.OnEventName("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.On("CompletionEvent", "slow_handler", func(event *abxbus.BaseEvent) (any, error) { slowStarted <- struct{}{} time.Sleep(500 * time.Millisecond) slowCompleted <- struct{}{} return "slow", nil }, nil) - bus.OnEventName("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { + bus.On("CompletionEvent", "fast_handler", func(event *abxbus.BaseEvent) (any, error) { time.Sleep(10 * time.Millisecond) return "winner", nil }, nil) - event := bus.EmitEventName("CompletionEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("CompletionEvent", nil)) _, err := event.Now(&abxbus.EventWaitOptions{FirstResult: true}) if err != nil { panic(err) diff --git a/docs/concurrency/handlers-parallel.mdx b/docs/concurrency/handlers-parallel.mdx index a9ab6008..6952782b 100644 --- a/docs/concurrency/handlers-parallel.mdx +++ b/docs/concurrency/handlers-parallel.mdx @@ -126,10 +126,10 @@ func main() { return nil, nil } - bus.OnEventName("HandlerEvent", "tracked_a", tracked, nil) - bus.OnEventName("HandlerEvent", "tracked_b", tracked, nil) + bus.On("HandlerEvent", "tracked_a", tracked, nil) + bus.On("HandlerEvent", "tracked_b", tracked, nil) - event := bus.EmitEventName("HandlerEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("HandlerEvent", nil)) <-started <-started close(release) diff --git a/docs/concurrency/handlers-serial.mdx b/docs/concurrency/handlers-serial.mdx index 46d9f03b..b549c25b 100644 --- a/docs/concurrency/handlers-serial.mdx +++ b/docs/concurrency/handlers-serial.mdx @@ -97,21 +97,21 @@ func main() { }) log := []string{} - bus.OnEventName("HandlerEvent", "h1", func(event *abxbus.BaseEvent) (any, error) { + bus.On("HandlerEvent", "h1", func(event *abxbus.BaseEvent) (any, error) { log = append(log, "h1_start") time.Sleep(10 * time.Millisecond) log = append(log, "h1_end") return nil, nil }, nil) - bus.OnEventName("HandlerEvent", "h2", func(event *abxbus.BaseEvent) (any, error) { + bus.On("HandlerEvent", "h2", func(event *abxbus.BaseEvent) (any, error) { log = append(log, "h2_start") time.Sleep(10 * time.Millisecond) log = append(log, "h2_end") return nil, nil }, nil) - event := bus.EmitEventName("HandlerEvent", nil) + event := bus.Emit(abxbus.NewBaseEvent("HandlerEvent", nil)) if _, err := event.Now(); err != nil { panic(err) } diff --git a/docs/concurrency/immediate-execution.mdx b/docs/concurrency/immediate-execution.mdx index e0eda6aa..9be935d1 100644 --- a/docs/concurrency/immediate-execution.mdx +++ b/docs/concurrency/immediate-execution.mdx @@ -102,8 +102,8 @@ bus.on(ChildEvent, |_event: ChildEvent| async move { ```go bus := abxbus.NewEventBus("RpcBus", nil) -bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { - child := event.EmitEventName("ChildEvent", nil) +bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { + child := event.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } @@ -114,7 +114,7 @@ bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, return fmt.Sprintf("parent got: %v", value), nil }, nil) -bus.OnEventName("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { +bus.On("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { return "child response", nil }, nil) ``` @@ -202,11 +202,11 @@ bus := abxbus.NewEventBus("ParallelRpcBus", &abxbus.EventBusOptions{ EventConcurrency: abxbus.EventConcurrencyParallel, }) -bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { +bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { children := []*abxbus.BaseEvent{ - event.EmitEventName("SomeChildEvent1", nil), - event.EmitEventName("SomeChildEvent2", nil), - event.EmitEventName("SomeChildEvent3", nil), + event.Emit(abxbus.NewBaseEvent("SomeChildEvent1", nil)), + event.Emit(abxbus.NewBaseEvent("SomeChildEvent2", nil)), + event.Emit(abxbus.NewBaseEvent("SomeChildEvent3", nil)), } for _, child := range children { @@ -363,11 +363,11 @@ bus := abxbus.NewEventBus("OrderBus", &abxbus.EventBusOptions{ }) order := []string{} -bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { +bus.On("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, error) { order = append(order, "parent_start") // Detached top-level work: no parent link is recorded for the sibling. - bus.EmitEventName("SiblingEvent", nil) - child := event.EmitEventName("ChildEvent", nil) + bus.Emit(abxbus.NewBaseEvent("SiblingEvent", nil)) + child := event.Emit(abxbus.NewBaseEvent("ChildEvent", nil)) if _, err := child.Now(); err != nil { return nil, err } @@ -375,17 +375,17 @@ bus.OnEventName("ParentEvent", "on_parent", func(event *abxbus.BaseEvent) (any, return nil, nil }, nil) -bus.OnEventName("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { +bus.On("ChildEvent", "on_child", func(event *abxbus.BaseEvent) (any, error) { order = append(order, "child") return nil, nil }, nil) -bus.OnEventName("SiblingEvent", "on_sibling", func(event *abxbus.BaseEvent) (any, error) { +bus.On("SiblingEvent", "on_sibling", func(event *abxbus.BaseEvent) (any, error) { order = append(order, "sibling") return nil, nil }, nil) -parent := bus.EmitEventName("ParentEvent", nil) +parent := bus.Emit(abxbus.NewBaseEvent("ParentEvent", nil)) if _, err := parent.Now(); err != nil { panic(err) } diff --git a/docs/concurrency/timeouts.mdx b/docs/concurrency/timeouts.mdx index ba9e9d0c..25cb9ca9 100644 --- a/docs/concurrency/timeouts.mdx +++ b/docs/concurrency/timeouts.mdx @@ -213,7 +213,7 @@ bus.on(WorkEvent, slowHandler, { ```go -entry := bus.OnEventName("WorkEvent", "slow_handler", slowHandler, nil) +entry := bus.On("WorkEvent", "slow_handler", slowHandler, nil) handlerTimeout := 1.5 handlerSlowTimeout := 0.5 entry.HandlerTimeout = &handlerTimeout diff --git a/docs/features/async-sync-handlers.mdx b/docs/features/async-sync-handlers.mdx index 6854a6c3..a67aa0f6 100644 --- a/docs/features/async-sync-handlers.mdx +++ b/docs/features/async-sync-handlers.mdx @@ -198,9 +198,9 @@ func main() { bus := abxbus.NewEventBus("AppBus", nil) handlers := &HandlerSet{Prefix: "svc"} - bus.OnEventName("WorkEvent", "bare_handler", bareHandler, nil) - bus.OnEventName("WorkEvent", "static_style_handler", StaticStyleHandler, nil) - bus.OnEventName("WorkEvent", "instance_handler", handlers.InstanceHandler, nil) + bus.On("WorkEvent", "bare_handler", bareHandler, nil) + bus.On("WorkEvent", "static_style_handler", StaticStyleHandler, nil) + bus.On("WorkEvent", "instance_handler", handlers.InstanceHandler, nil) } ``` diff --git a/docs/features/context-propagation.mdx b/docs/features/context-propagation.mdx index b505a8b8..32fcb10a 100644 --- a/docs/features/context-propagation.mdx +++ b/docs/features/context-propagation.mdx @@ -120,14 +120,14 @@ func main() { requestIDKey := contextKey("request_id") bus := abxbus.NewEventBus("AppBus", nil) - bus.OnEventName("RequestEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { + bus.On("RequestEvent", "handler", func(event *abxbus.BaseEvent, ctx context.Context) (any, error) { fmt.Println(ctx.Value(requestIDKey)) // req-123 return nil, nil }, nil) ctx := context.WithValue(context.Background(), requestIDKey, "req-123") - if _, err := bus.EmitEventNameWithContext(ctx, "RequestEvent", nil).Now(); err != nil { + if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("RequestEvent", nil)).Now(); err != nil { panic(err) } } @@ -179,7 +179,7 @@ block_on(event.now()); ```go // net/http-style shape (conceptual) ctx := context.WithValue(req.Context(), requestIDKey, req.Header.Get("x-request-id")) -if _, err := bus.EmitEventNameWithContext(ctx, "RequestEvent", nil).Now(); err != nil { +if _, err := bus.EmitWithContext(ctx, abxbus.NewBaseEvent("RequestEvent", nil)).Now(); err != nil { panic(err) } // handlers can still read ctx.Value(requestIDKey) diff --git a/docs/features/event-debouncing.mdx b/docs/features/event-debouncing.mdx index 76fed787..eb7a627f 100644 --- a/docs/features/event-debouncing.mdx +++ b/docs/features/event-debouncing.mdx @@ -113,7 +113,7 @@ if err != nil { event := existing if event == nil { - event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) + event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) } if _, err := event.Now(); err != nil { panic(err) @@ -198,7 +198,7 @@ if err != nil { event := inFlight if event == nil { - event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) + event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) } if _, err := event.Now(); err != nil { panic(err) @@ -296,7 +296,7 @@ if event == nil { } } if event == nil { - event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) + event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) } if _, err := event.Now(); err != nil { @@ -396,7 +396,7 @@ func emitDebouncedScreenshot(ctx context.Context, bus *abxbus.EventBus, url stri } } if event == nil { - event = bus.EmitEventName("ScreenshotEvent", map[string]any{"url": url}) + event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", map[string]any{"url": url})) } if _, err := event.Now(); err != nil { diff --git a/docs/features/event-history-store.mdx b/docs/features/event-history-store.mdx index 1e1eb037..b6fdebd7 100644 --- a/docs/features/event-history-store.mdx +++ b/docs/features/event-history-store.mdx @@ -161,7 +161,7 @@ console.log('after completion -> pending_event_queue=', bus.pending_event_queue. ```go -event := bus.EmitEventName("MyEvent", nil) +event := bus.Emit(abxbus.NewBaseEvent("MyEvent", nil)) var before struct { PendingEventQueue []string `json:"pending_event_queue"` diff --git a/docs/features/event-pattern-matching.mdx b/docs/features/event-pattern-matching.mdx index cfd264bf..af77031d 100644 --- a/docs/features/event-pattern-matching.mdx +++ b/docs/features/event-pattern-matching.mdx @@ -154,23 +154,18 @@ import ( abxbus "github.com/ArchiveBox/abxbus/abxbus-go/v2" ) -type UserActionPayload struct { +type UserActionEvent struct { Action string `json:"action"` } func main() { bus := abxbus.NewEventBus("AppBus", nil) - bus.On( - "UserActionEvent", - "on", - func(payload UserActionPayload) (string, error) { - return fmt.Sprintf("action:%s", payload.Action), nil - }, - nil, - ) + bus.On(func(event UserActionEvent) (string, error) { + return fmt.Sprintf("action:%s", event.Action), nil + }) - bus.OnEventName("UserActionEvent", "on_by_name", func(event *abxbus.BaseEvent) (any, error) { + bus.On("UserActionEvent", "on_by_name", func(event *abxbus.BaseEvent) (any, error) { fmt.Println("by-name", event.EventType, event.Payload["action"]) // by-name UserActionEvent click return nil, nil @@ -182,15 +177,7 @@ func main() { return nil, nil }, nil) - event, err := abxbus.NewEvent[UserActionPayload]( - "UserActionEvent", - UserActionPayload{Action: "click"}, - abxbus.ResultType[string](), - ) - if err != nil { - panic(err) - } - _, err = bus.Emit(event).EventResult() + _, err := bus.Emit(UserActionEvent{Action: "click"}).EventResult() if err != nil { panic(err) } diff --git a/docs/features/fifo-processing.mdx b/docs/features/fifo-processing.mdx index 91114826..70847848 100644 --- a/docs/features/fifo-processing.mdx +++ b/docs/features/fifo-processing.mdx @@ -132,7 +132,7 @@ func main() { startedOrder := []int{} completedOrder := []int{} - bus.OnEventName("JobEvent", "on_job", func(event *abxbus.BaseEvent) (any, error) { + bus.On("JobEvent", "on_job", func(event *abxbus.BaseEvent) (any, error) { order := event.Payload["order"].(int) delayMS := event.Payload["delay_ms"].(int) startedOrder = append(startedOrder, order) @@ -142,9 +142,9 @@ func main() { }, nil) emitted := []*abxbus.BaseEvent{ - bus.EmitEventName("JobEvent", map[string]any{"order": 0, "delay_ms": 30}), - bus.EmitEventName("JobEvent", map[string]any{"order": 1, "delay_ms": 1}), - bus.EmitEventName("JobEvent", map[string]any{"order": 2, "delay_ms": 20}), + bus.Emit(abxbus.NewBaseEvent("JobEvent", map[string]any{"order": 0, "delay_ms": 30})), + bus.Emit(abxbus.NewBaseEvent("JobEvent", map[string]any{"order": 1, "delay_ms": 1})), + bus.Emit(abxbus.NewBaseEvent("JobEvent", map[string]any{"order": 2, "delay_ms": 20})), } bus.WaitUntilIdle(nil) @@ -306,22 +306,22 @@ console.log(treeLines) bus := abxbus.NewEventBus("FifoBus", nil) trace := []string{} -bus.OnEventName("SlowEvent", "on_slow", func(event *abxbus.BaseEvent) (any, error) { +bus.On("SlowEvent", "on_slow", func(event *abxbus.BaseEvent) (any, error) { trace = append(trace, fmt.Sprintf("start:%s:%s", event.EventType, event.Payload["name"])) time.Sleep(40 * time.Millisecond) trace = append(trace, fmt.Sprintf("end:%s:%s", event.EventType, event.Payload["name"])) return nil, nil }, nil) -bus.OnEventName("FastEvent", "on_fast", func(event *abxbus.BaseEvent) (any, error) { +bus.On("FastEvent", "on_fast", func(event *abxbus.BaseEvent) (any, error) { trace = append(trace, fmt.Sprintf("start:%s:%s", event.EventType, event.Payload["name"])) time.Sleep(1 * time.Millisecond) trace = append(trace, fmt.Sprintf("end:%s:%s", event.EventType, event.Payload["name"])) return nil, nil }, nil) -slow := bus.EmitEventName("SlowEvent", map[string]any{"name": "slow-a"}) -fast := bus.EmitEventName("FastEvent", map[string]any{"name": "fast-b"}) +slow := bus.Emit(abxbus.NewBaseEvent("SlowEvent", map[string]any{"name": "slow-a"})) +fast := bus.Emit(abxbus.NewBaseEvent("FastEvent", map[string]any{"name": "fast-b"})) bus.WaitUntilIdle(nil) fmt.Println(trace) diff --git a/docs/features/find-events.mdx b/docs/features/find-events.mdx index be955574..567677ed 100644 --- a/docs/features/find-events.mdx +++ b/docs/features/find-events.mdx @@ -373,9 +373,9 @@ const child = await bus.find(TabCreatedEvent, { child_of: parentEvent, past: 5 } ```go -parentEvent := bus.EmitEventName("NavigateToUrlEvent", map[string]any{ +parentEvent := bus.Emit(abxbus.NewBaseEvent("NavigateToUrlEvent", map[string]any{ "url": "https://example.com", -}) +})) if _, err := parentEvent.Now(); err != nil { panic(err) } @@ -463,7 +463,7 @@ if event == nil { } } if event == nil { - event = bus.EmitEventName("ScreenshotEvent", nil) + event = bus.Emit(abxbus.NewBaseEvent("ScreenshotEvent", nil)) } if _, err := event.Now(); err != nil { panic(err) diff --git a/docs/features/forwarding-between-buses.mdx b/docs/features/forwarding-between-buses.mdx index 60fdba5c..48efe417 100644 --- a/docs/features/forwarding-between-buses.mdx +++ b/docs/features/forwarding-between-buses.mdx @@ -274,10 +274,10 @@ func main() { MaxHistorySize: &maxHistory, })} - auth.bus.OnEventName("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { + auth.bus.On("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("auth-ok:%s", event.Payload["user_id"]), nil }, nil) - billing.bus.OnEventName("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { + billing.bus.On("UserCreatedEvent", "on_user_created", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("billing-ok:%s", event.Payload["user_id"]), nil }, nil) @@ -288,7 +288,7 @@ func main() { return billing.bus.Emit(event), nil }, nil) - event := auth.bus.EmitEventName("UserCreatedEvent", map[string]any{"user_id": "u-a8d1"}) + event := auth.bus.Emit(abxbus.NewBaseEvent("UserCreatedEvent", map[string]any{"user_id": "u-a8d1"})) result, err := event.EventResult() if err != nil { panic(err) @@ -519,7 +519,7 @@ busC.OnEventName("*", "forward_to_a", func(event *abxbus.BaseEvent) (any, error) return busA.Emit(event), nil }, nil) -event := busA.EmitEventName("PingEvent", map[string]any{"message": "hello"}) +event := busA.Emit(abxbus.NewBaseEvent("PingEvent", map[string]any{"message": "hello"})) if _, err := event.Now(); err != nil { panic(err) } diff --git a/docs/features/parent-child-tracking.mdx b/docs/features/parent-child-tracking.mdx index 8a132a36..0f4e7279 100644 --- a/docs/features/parent-child-tracking.mdx +++ b/docs/features/parent-child-tracking.mdx @@ -44,9 +44,9 @@ In Rust, the same split is explicit: In Go, the same split is explicit: -- `child := event.EmitEventName(...)` creates linked child work. +- `child := event.Emit(ChildEvent{...})` creates linked child work. - `child.Now()` queue-jumps and waits for that linked child. -- `bus.EmitEventName(...)` creates detached top-level work. +- `bus.Emit(ParentEvent{...})` creates detached top-level work. - calling `Now()` on a bus-emitted event waits for it without adding parent-child lineage. ## Works across forwarded buses too @@ -293,10 +293,10 @@ import ( func main() { bus := abxbus.NewEventBus("TreeBus", nil) - bus.OnEventName("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { + bus.On("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { orderID := event.Payload["order_id"].(string) - reserve := event.EmitEventName("ReserveInventoryEvent", map[string]any{"order_id": orderID}) + reserve := event.Emit(abxbus.NewBaseEvent("ReserveInventoryEvent", map[string]any{"order_id": orderID})) if _, err := reserve.Now(); err != nil { return nil, err } @@ -305,7 +305,7 @@ func main() { return nil, err } - charge := event.EmitEventName("ChargeCardEvent", map[string]any{"order_id": orderID}) + charge := event.Emit(abxbus.NewBaseEvent("ChargeCardEvent", map[string]any{"order_id": orderID})) if _, err := charge.Now(); err != nil { return nil, err } @@ -314,7 +314,7 @@ func main() { return nil, err } - receipt := event.EmitEventName("SendReceiptEvent", map[string]any{"order_id": orderID}) + receipt := event.Emit(abxbus.NewBaseEvent("SendReceiptEvent", map[string]any{"order_id": orderID})) if _, err := receipt.Now(); err != nil { return nil, err } @@ -326,13 +326,13 @@ func main() { return fmt.Sprintf("%v|%v|%v", reserveID, chargeID, receiptID), nil }, nil) - bus.OnEventName("ReserveInventoryEvent", "on_reserve", func(event *abxbus.BaseEvent) (any, error) { + bus.On("ReserveInventoryEvent", "on_reserve", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("reserve:%s", event.Payload["order_id"]), nil }, nil) - bus.OnEventName("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { + bus.On("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { orderID := event.Payload["order_id"].(string) - fraud := event.EmitEventName("FraudCheckEvent", map[string]any{"order_id": orderID}) + fraud := event.Emit(abxbus.NewBaseEvent("FraudCheckEvent", map[string]any{"order_id": orderID})) if _, err := fraud.Now(); err != nil { return nil, err } @@ -343,14 +343,14 @@ func main() { return fmt.Sprintf("charge:%s:%v", orderID, fraudStatus), nil }, nil) - bus.OnEventName("FraudCheckEvent", "on_fraud", func(event *abxbus.BaseEvent) (any, error) { + bus.On("FraudCheckEvent", "on_fraud", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("fraud-ok:%s", event.Payload["order_id"]), nil }, nil) - bus.OnEventName("SendReceiptEvent", "on_receipt", func(event *abxbus.BaseEvent) (any, error) { + bus.On("SendReceiptEvent", "on_receipt", func(event *abxbus.BaseEvent) (any, error) { return fmt.Sprintf("receipt:%s", event.Payload["order_id"]), nil }, nil) - root := bus.EmitEventName("CheckoutEvent", map[string]any{"order_id": "ord-123"}) + root := bus.Emit(abxbus.NewBaseEvent("CheckoutEvent", map[string]any{"order_id": "ord-123"})) result, err := root.EventResult() if err != nil { panic(err) diff --git a/docs/features/return-value-handling.mdx b/docs/features/return-value-handling.mdx index 115d72b2..2e476487 100644 --- a/docs/features/return-value-handling.mdx +++ b/docs/features/return-value-handling.mdx @@ -87,30 +87,17 @@ let result = block_on(event.event_result())?; ```go -type DoMathPayload struct { +type DoMathEvent struct { A int `json:"a"` B int `json:"b"` } bus := abxbus.NewEventBus("AppBus", nil) -bus.On( - "DoMathEvent", - "add", - func(payload DoMathPayload) (int, error) { - return payload.A + payload.B, nil - }, - nil, -) +bus.On(func(event DoMathEvent) (int, error) { + return event.A + event.B, nil +}) -event, err := abxbus.NewEvent[DoMathPayload]( - "DoMathEvent", - DoMathPayload{A: 2, B: 3}, - abxbus.ResultType[int](), -) -if err != nil { - panic(err) -} -emitted := bus.Emit(event) +emitted := bus.Emit(DoMathEvent{A: 2, B: 3}) result, err := emitted.EventResult() ``` @@ -177,7 +164,9 @@ let values = block_on(event.event_results_list_with_options(EventResultOptions { ```go -event := bus.EmitEventName("GetConfigEvent", nil) +type GetConfigEvent struct{} + +event := bus.Emit(GetConfigEvent{}) values, err := event.EventResultsList( &abxbus.EventResultOptions{RaiseIfAny: false, RaiseIfNone: false}, ) diff --git a/docs/features/typed-events.mdx b/docs/features/typed-events.mdx index f4b95ad4..a96695db 100644 --- a/docs/features/typed-events.mdx +++ b/docs/features/typed-events.mdx @@ -92,7 +92,7 @@ let typed_result = block_on(event.event_result())? ```go -type OrderCreatedPayload struct { +type OrderCreatedEvent struct { OrderID string `json:"order_id"` CustomerID string `json:"customer_id"` TotalAmount float64 `json:"total_amount"` @@ -103,25 +103,15 @@ type OrderResult struct { } bus := abxbus.NewEventBus("OrdersBus", nil) -bus.On( - "OrderCreatedEvent", - "handle_order", - func(payload OrderCreatedPayload) (OrderResult, error) { - return OrderResult{OK: payload.TotalAmount > 0}, nil - }, - nil, -) - -event, err := abxbus.NewEvent[OrderCreatedPayload]("OrderCreatedEvent", OrderCreatedPayload{ +bus.On(func(event OrderCreatedEvent) (OrderResult, error) { + return OrderResult{OK: event.TotalAmount > 0}, nil +}) + +result, err := bus.Emit(OrderCreatedEvent{ OrderID: "order-123", CustomerID: "customer-456", TotalAmount: 42.50, -}, abxbus.ResultType[OrderResult]()) -if err != nil { - panic(err) -} - -result, err := bus.Emit(event).EventResult() +}).EventResult() if err != nil { panic(err) } diff --git a/docs/further-reading/events-suck.mdx b/docs/further-reading/events-suck.mdx index 3d104f98..0a0100ff 100644 --- a/docs/further-reading/events-suck.mdx +++ b/docs/further-reading/events-suck.mdx @@ -59,10 +59,10 @@ const updated = await client.update({ id: id ?? 'fallback-id', age: 46 }, { sour // events_suck is not implemented in abxbus-go yet. // // Use the core EventBus APIs directly: -event := bus.EmitEventName("CreateUserEvent", map[string]any{ +event := bus.Emit(abxbus.NewBaseEvent("CreateUserEvent", map[string]any{ "name": "bob", "age": 45, -}) +})) userID, err := event.EventResult() ``` @@ -179,7 +179,7 @@ const updated = await client.update({ id: user_id ?? 'fallback-id', age: 46 }, { ```go // events_suck.wrap/make_events/make_handler are not implemented in Go yet. -// For typed event APIs, use bus.On(...) and NewEvent(..., ResultType[T]()). +// For typed event APIs, use bus.On(func(MyEvent) ...) and bus.Emit(MyEvent{...}). ``` @@ -259,16 +259,16 @@ bus.on(ChargeCardEvent, async (event) => `receipt-${event.order_id}`) ```go -bus.OnEventName("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { +bus.On("CheckoutEvent", "on_checkout", func(event *abxbus.BaseEvent) (any, error) { orderID, _ := event.Payload["order_id"].(string) - child := event.EmitEventName("ChargeCardEvent", map[string]any{"order_id": orderID}) + child := event.Emit(abxbus.NewBaseEvent("ChargeCardEvent", map[string]any{"order_id": orderID})) if _, err := child.Now(); err != nil { return nil, err } return child.EventResult() }, nil) -bus.OnEventName("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { +bus.On("ChargeCardEvent", "on_charge", func(event *abxbus.BaseEvent) (any, error) { orderID, _ := event.Payload["order_id"].(string) return "receipt-" + orderID, nil }, nil) diff --git a/docs/index.mdx b/docs/index.mdx index 6e7fb25d..55a1925e 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -99,13 +99,16 @@ import ( ) func main() { + type SomeEvent struct { + SomeData int `json:"some_data"` + } + bus := abxbus.NewEventBus("MyBus", nil) - bus.OnEventName("SomeEvent", "on_some_event", func(event *abxbus.BaseEvent) (any, error) { - fmt.Println(event.Payload["some_data"]) - return nil, nil - }, nil) + bus.On(func(event SomeEvent) { + fmt.Println(event.SomeData) + }) - event := bus.EmitEventName("SomeEvent", map[string]any{"some_data": 132}) + event := bus.Emit(SomeEvent{SomeData: 132}) _, _ = event.Now() } ``` diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 27981c85..abbb3858 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -134,14 +134,20 @@ block_on(async { ```go -bus := abxbus.NewEventBus("MyAuthEventBus", nil) -bus.OnEventName("CreateUserEvent", "on_create_user", func(event *abxbus.BaseEvent) (any, error) { - return map[string]any{"user_id": "some-user-uuid"}, nil -}, nil) +type CreateUserEvent struct { + Email string `json:"email"` +} + +type CreateUserResult struct { + UserID string `json:"user_id"` +} -event := bus.EmitEventName("CreateUserEvent", map[string]any{ - "email": "someuser@example.com", +bus := abxbus.NewEventBus("MyAuthEventBus", nil) +bus.On(func(event CreateUserEvent) (CreateUserResult, error) { + return CreateUserResult{UserID: "some-user-uuid"}, nil }) + +event := bus.Emit(CreateUserEvent{Email: "someuser@example.com"}) result, err := event.EventResult() if err != nil { panic(err) From 2588bd3f78de2312c2e070eaee317cd4e1546c70 Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Thu, 14 May 2026 11:46:55 -0700 Subject: [PATCH 3/5] Infer event result types from zod event schemas --- abxbus-ts/src/BaseEvent.ts | 6 +++++- abxbus-ts/src/type_inference.test.ts | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/abxbus-ts/src/BaseEvent.ts b/abxbus-ts/src/BaseEvent.ts index 9aafbf86..a7b52977 100644 --- a/abxbus-ts/src/BaseEvent.ts +++ b/abxbus-ts/src/BaseEvent.ts @@ -161,6 +161,7 @@ type ResultTypeFromEventResultTypeInput = TInput extends z.ZodTypeAny : unknown type ResultSchemaFromShape = TShape extends { event_result_type: infer S } ? ResultTypeFromEventResultTypeInput : unknown +type ResultSchemaFromEventSchema = TSchema extends z.ZodObject ? ResultSchemaFromShape : unknown export type EventResultInclude = ( result: EventResult['result'], event_result: EventResult @@ -465,7 +466,10 @@ export class BaseEvent { // main entry point for users to define their own event types // BaseEvent.extend("MyEvent", { some_custom_field: z.string(), event_result_type: z.string(), event_timeout: 25, ... }) -> MyEvent - static extend>(event_type: string, event_schema: TSchema): SchemaEventFactory + static extend>( + event_type: string, + event_schema: TSchema + ): SchemaEventFactory> static extend(event_type: string, shape?: TShape): EventFactory> static extend>( event_type: string, diff --git a/abxbus-ts/src/type_inference.test.ts b/abxbus-ts/src/type_inference.test.ts index 6b52a15d..dd02cb16 100644 --- a/abxbus-ts/src/type_inference.test.ts +++ b/abxbus-ts/src/type_inference.test.ts @@ -17,8 +17,18 @@ const InferableResultEvent = BaseEvent.extend('InferableResultEvent', { event_result_type: z.object({ ok: z.boolean() }), }) +const InferableZodObjectResultEvent = BaseEvent.extend( + 'InferableZodObjectResultEvent', + z.object({ + target_id: z.string(), + event_result_type: z.object({ ok: z.boolean() }), + }) +) + type InferableResult = EventResultType> type _assert_inferable_result = Assert> +type InferableZodObjectResult = EventResultType> +type _assert_inferable_zod_object_result = Assert> type InferableEventResultEntry = InstanceType['event_results'] extends Map ? TResultEntry : never type _assert_inferable_event_result_entry = Assert< @@ -96,6 +106,14 @@ bus.on(InferableResultEvent, () => undefined) // @ts-expect-error non-void return must match event_result_type for inferable event keys bus.on(InferableResultEvent, () => 'not-ok') +bus.on(InferableZodObjectResultEvent, (event) => { + const target: string = event.target_id + return { ok: target.length > 0 } +}) + +// @ts-expect-error z.object event_result_type must also enforce handler return shape +bus.on(InferableZodObjectResultEvent, () => 'not-ok') + // String/wildcard keys remain best-effort and do not strongly enforce return shapes. bus.on('InferableResultEvent', () => 'anything') bus.on('*', () => 123) From 380cfe17a0440478d3549e78ff01945177f493e8 Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Thu, 14 May 2026 11:52:27 -0700 Subject: [PATCH 4/5] release: 2.5.1 --- abxbus-go/version.go | 2 +- abxbus-rust/Cargo.lock | 2 +- abxbus-rust/Cargo.toml | 2 +- abxbus-ts/package.json | 2 +- pyproject.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/abxbus-go/version.go b/abxbus-go/version.go index e99ade2e..3d96882a 100644 --- a/abxbus-go/version.go +++ b/abxbus-go/version.go @@ -1,3 +1,3 @@ package abxbus -const Version = "2.5.0" +const Version = "2.5.1" diff --git a/abxbus-rust/Cargo.lock b/abxbus-rust/Cargo.lock index 9a5f1edd..683af4f6 100644 --- a/abxbus-rust/Cargo.lock +++ b/abxbus-rust/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "abxbus-rust" -version = "2.5.0" +version = "2.5.1" dependencies = [ "chrono", "dcontext", diff --git a/abxbus-rust/Cargo.toml b/abxbus-rust/Cargo.toml index 727de697..010ee394 100644 --- a/abxbus-rust/Cargo.toml +++ b/abxbus-rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "abxbus-rust" -version = "2.5.0" +version = "2.5.1" edition = "2021" license = "MIT" description = "Rust implementation of the abxbus Event Bus library" diff --git a/abxbus-ts/package.json b/abxbus-ts/package.json index b6ddd328..f353b18e 100644 --- a/abxbus-ts/package.json +++ b/abxbus-ts/package.json @@ -1,6 +1,6 @@ { "name": "abxbus", - "version": "2.5.0", + "version": "2.5.1", "description": "Event bus library for browsers and ESM Node.js", "type": "module", "sideEffects": false, diff --git a/pyproject.toml b/pyproject.toml index ebf5c178..389fbd75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "abxbus" description = "Advanced Pydantic-powered event bus with async support" authors = [{ name = "Nick Sweeting" }, { name = "ArchiveBox" }] -version = "2.5.0" +version = "2.5.1" readme = "README.md" requires-python = ">=3.11" classifiers = [ From 6d1f08fab9e7dc2266e591c12e480cd1ac0bc607 Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Fri, 15 May 2026 13:51:24 -0700 Subject: [PATCH 5/5] release: 2.5.2 --- abxbus-go/jsonschema/jsonschema.go | 127 +++++++++++++++++++----- abxbus-go/jsonschema/jsonschema_test.go | 25 +++++ abxbus-go/version.go | 2 +- abxbus-rust/Cargo.lock | 2 +- abxbus-rust/Cargo.toml | 2 +- abxbus-ts/package.json | 2 +- pyproject.toml | 2 +- 7 files changed, 133 insertions(+), 29 deletions(-) diff --git a/abxbus-go/jsonschema/jsonschema.go b/abxbus-go/jsonschema/jsonschema.go index 7c831417..e7e97629 100644 --- a/abxbus-go/jsonschema/jsonschema.go +++ b/abxbus-go/jsonschema/jsonschema.go @@ -52,6 +52,28 @@ func SchemaForValue(value any) map[string]any { // SchemaForType returns a small JSON Schema object for t. func SchemaForType(t reflect.Type) map[string]any { + state := schemaForState{ + defs: map[string]any{}, + inProgress: map[reflect.Type]string{}, + typeNames: map[reflect.Type]string{}, + usedNames: map[string]reflect.Type{}, + } + schema := state.schemaForType(t) + if len(state.defs) > 0 { + schema = cloneSchemaMap(schema) + schema["$defs"] = state.defs + } + return schema +} + +type schemaForState struct { + defs map[string]any + inProgress map[reflect.Type]string + typeNames map[reflect.Type]string + usedNames map[string]reflect.Type +} + +func (state *schemaForState) schemaForType(t reflect.Type) map[string]any { for t != nil && t.Kind() == reflect.Pointer { t = t.Elem() } @@ -60,31 +82,20 @@ func SchemaForType(t reflect.Type) map[string]any { } switch t.Kind() { case reflect.Struct: - properties := map[string]any{} - required := []any{} - for i := 0; i < t.NumField(); i++ { - field := t.Field(i) - if field.PkgPath != "" { - continue - } - name, omitEmpty, skip := jsonFieldName(field) - if skip { - continue + if name := state.schemaRefName(t); name != "" { + if _, ok := state.defs[name]; ok { + return map[string]any{"$ref": "#/$defs/" + name} } - properties[name] = SchemaForType(field.Type) - if !omitEmpty && !isOptionalType(field.Type) { - required = append(required, name) + if _, ok := state.inProgress[t]; ok { + return map[string]any{"$ref": "#/$defs/" + name} } + state.inProgress[t] = name + schema := state.schemaForStruct(t) + delete(state.inProgress, t) + state.defs[name] = schema + return schema } - schema := map[string]any{ - "type": "object", - "properties": properties, - "additionalProperties": false, - } - if len(required) > 0 { - schema["required"] = required - } - return schema + return state.schemaForStruct(t) case reflect.String: return map[string]any{"type": "string"} case reflect.Bool: @@ -95,14 +106,82 @@ func SchemaForType(t reflect.Type) map[string]any { case reflect.Float32, reflect.Float64: return map[string]any{"type": "number"} case reflect.Slice, reflect.Array: - return map[string]any{"type": "array", "items": SchemaForType(t.Elem())} + return map[string]any{"type": "array", "items": state.schemaForType(t.Elem())} case reflect.Map: - return map[string]any{"type": "object", "additionalProperties": SchemaForType(t.Elem())} + return map[string]any{"type": "object", "additionalProperties": state.schemaForType(t.Elem())} default: return map[string]any{} } } +func (state *schemaForState) schemaForStruct(t reflect.Type) map[string]any { + properties := map[string]any{} + required := []any{} + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if field.PkgPath != "" { + continue + } + name, omitEmpty, skip := jsonFieldName(field) + if skip { + continue + } + properties[name] = state.schemaForType(field.Type) + if !omitEmpty && !isOptionalType(field.Type) { + required = append(required, name) + } + } + schema := map[string]any{ + "type": "object", + "properties": properties, + "additionalProperties": false, + } + if len(required) > 0 { + schema["required"] = required + } + return schema +} + +func (state *schemaForState) schemaRefName(t reflect.Type) string { + if t.Name() == "" { + return "" + } + if name, ok := state.typeNames[t]; ok { + return name + } + base := sanitizeSchemaRefName(t.PkgPath() + "." + t.Name()) + name := base + for i := 2; ; i++ { + existing, ok := state.usedNames[name] + if !ok || existing == t { + state.usedNames[name] = t + state.typeNames[t] = name + return name + } + name = fmt.Sprintf("%s_%d", base, i) + } +} + +func sanitizeSchemaRefName(name string) string { + var builder strings.Builder + for _, r := range name { + if r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '_' || r == '-' || r == '.' { + builder.WriteRune(r) + } else { + builder.WriteByte('_') + } + } + return builder.String() +} + +func cloneSchemaMap(schema map[string]any) map[string]any { + clone := make(map[string]any, len(schema)+1) + for key, value := range schema { + clone[key] = value + } + return clone +} + func jsonFieldName(field reflect.StructField) (string, bool, bool) { tag := field.Tag.Get("json") if tag == "-" { diff --git a/abxbus-go/jsonschema/jsonschema_test.go b/abxbus-go/jsonschema/jsonschema_test.go index dd5ef372..52c767bc 100644 --- a/abxbus-go/jsonschema/jsonschema_test.go +++ b/abxbus-go/jsonschema/jsonschema_test.go @@ -86,3 +86,28 @@ func TestSchemaForStructUsesJSONNamesAndValidates(t *testing.T) { t.Fatalf("expected generated schema to reject wrong id type, got %v", err) } } + +func TestSchemaForRecursiveStructUsesRefsAndValidates(t *testing.T) { + type Node struct { + ID string `json:"id"` + Children []Node `json:"children,omitempty"` + Parent *Node `json:"parent,omitempty"` + } + + schema := jsonschema.SchemaFor[Node]() + if _, ok := schema["$defs"].(map[string]any); !ok { + t.Fatalf("expected recursive schema defs, got %#v", schema) + } + if err := jsonschema.Validate(schema, Node{ID: "root", Children: []Node{{ID: "child"}}}); err != nil { + t.Fatalf("expected recursive struct value to validate: %v", err) + } + payload := map[string]any{ + "id": "root", + "children": []any{ + map[string]any{"id": 3}, + }, + } + if err := jsonschema.Validate(schema, payload); err == nil || !strings.Contains(err.Error(), "expected string") { + t.Fatalf("expected generated recursive schema to reject wrong child id type, got %v", err) + } +} diff --git a/abxbus-go/version.go b/abxbus-go/version.go index 3d96882a..f815a07e 100644 --- a/abxbus-go/version.go +++ b/abxbus-go/version.go @@ -1,3 +1,3 @@ package abxbus -const Version = "2.5.1" +const Version = "2.5.2" diff --git a/abxbus-rust/Cargo.lock b/abxbus-rust/Cargo.lock index 683af4f6..4721daf1 100644 --- a/abxbus-rust/Cargo.lock +++ b/abxbus-rust/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "abxbus-rust" -version = "2.5.1" +version = "2.5.2" dependencies = [ "chrono", "dcontext", diff --git a/abxbus-rust/Cargo.toml b/abxbus-rust/Cargo.toml index 010ee394..73714d5f 100644 --- a/abxbus-rust/Cargo.toml +++ b/abxbus-rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "abxbus-rust" -version = "2.5.1" +version = "2.5.2" edition = "2021" license = "MIT" description = "Rust implementation of the abxbus Event Bus library" diff --git a/abxbus-ts/package.json b/abxbus-ts/package.json index f353b18e..73a065e8 100644 --- a/abxbus-ts/package.json +++ b/abxbus-ts/package.json @@ -1,6 +1,6 @@ { "name": "abxbus", - "version": "2.5.1", + "version": "2.5.2", "description": "Event bus library for browsers and ESM Node.js", "type": "module", "sideEffects": false, diff --git a/pyproject.toml b/pyproject.toml index 389fbd75..c7830d19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "abxbus" description = "Advanced Pydantic-powered event bus with async support" authors = [{ name = "Nick Sweeting" }, { name = "ArchiveBox" }] -version = "2.5.1" +version = "2.5.2" readme = "README.md" requires-python = ">=3.11" classifiers = [