Documentation
¶
Overview ¶
Package evobs provides a type-safe, generic event bus implementation inspired by the DOM EventTarget API. It supports synchronous and asynchronous event dispatch, cancelable events, context-aware subscriptions, and deterministic listener ordering.
Index ¶
- type AddOptions
- type BaseEvent
- type BasePropagation
- type Cancelable
- type EventTarget
- func (et *EventTarget[T]) Add(fn Listener[T]) *Subscription
- func (et *EventTarget[T]) AddOnce(fn Listener[T]) *Subscription
- func (et *EventTarget[T]) AddWithContext(ctx context.Context, fn Listener[T]) *Subscription
- func (et *EventTarget[T]) AddWithOptions(fn Listener[T], opt AddOptions) *Subscription
- func (et *EventTarget[T]) Clear()
- func (et *EventTarget[T]) Dispatch(ev T) bool
- func (et *EventTarget[T]) Len() int
- type Listener
- type PanicHandler
- type Stoppable
- type Subscription
- type Synchronous
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddOptions ¶
type AddOptions struct {
// Once causes the listener to automatically unsubscribe after
// being invoked once.
Once bool
// RecoverPanic wraps the listener invocation in a recover block,
// preventing panics from propagating and crashing the dispatcher.
// Useful for isolating untrusted or error-prone handlers.
RecoverPanic bool
}
AddOptions configures listener behavior, similar to the options parameter in addEventListener.
type BaseEvent ¶
type BaseEvent struct {
// contains filtered or unexported fields
}
BaseEvent provides DOM-like cancellation ("preventDefault") functionality. Embed this struct in your custom event types to make them cancelable.
Example:
type ClickEvent struct {
evobs.BaseEvent
X, Y int
}
func (*BaseEvent) DefaultPrevented ¶
DefaultPrevented atomically reads the cancelled flag.
func (*BaseEvent) PreventDefault ¶
func (b *BaseEvent) PreventDefault()
PreventDefault atomically sets the cancelled flag to true.
type BasePropagation ¶
type BasePropagation struct {
// contains filtered or unexported fields
}
BasePropagation provides DOM-like propagation stopping functionality. Embed this struct in your custom event types to support StopPropagation. Events embedding this will automatically be dispatched synchronously.
Example:
type ClickEvent struct {
evobs.BasePropagation
X, Y int
}
func (*BasePropagation) PropagationStopped ¶
func (b *BasePropagation) PropagationStopped() bool
PropagationStopped atomically reads the stopped flag.
func (*BasePropagation) StopPropagation ¶
func (b *BasePropagation) StopPropagation()
StopPropagation atomically sets the stopped flag to true.
type Cancelable ¶
type Cancelable interface {
// PreventDefault marks the event as cancelled, signaling that the
// default action should not occur.
PreventDefault()
// DefaultPrevented returns true if PreventDefault was called.
DefaultPrevented() bool
}
Cancelable is implemented by events that support PreventDefault semantics. This mirrors the DOM Event interface where handlers can prevent the default action associated with an event. If your event does not implement this interface, Dispatch will always return true (event not cancelled).
type EventTarget ¶
type EventTarget[T any] struct { // OnPanic is an optional callback invoked when a listener panics and // RecoverPanic is enabled. If nil, panics are silently discarded. // Must be safe for concurrent calls when using async dispatch. OnPanic PanicHandler // contains filtered or unexported fields }
EventTarget is a typed observer hub for events of type T. It guarantees deterministic listener invocation order based on registration sequence, making behavior predictable and testable.
The zero value is ready to use.
func (*EventTarget[T]) Add ¶
func (et *EventTarget[T]) Add(fn Listener[T]) *Subscription
Add registers a listener with default options. Returns a Subscription handle for later removal.
func (*EventTarget[T]) AddOnce ¶
func (et *EventTarget[T]) AddOnce(fn Listener[T]) *Subscription
AddOnce is a convenience method for registering a one-shot listener that automatically unsubscribes after its first invocation.
func (*EventTarget[T]) AddWithContext ¶
func (et *EventTarget[T]) AddWithContext(ctx context.Context, fn Listener[T]) *Subscription
AddWithContext registers a listener that automatically unsubscribes when the provided context is cancelled. Useful for tying listener lifecycle to request scopes or component lifetimes.
func (*EventTarget[T]) AddWithOptions ¶
func (et *EventTarget[T]) AddWithOptions(fn Listener[T], opt AddOptions) *Subscription
AddWithOptions registers a listener with custom configuration. This is the primary registration method; other Add* methods delegate here.
func (*EventTarget[T]) Clear ¶
func (et *EventTarget[T]) Clear()
Clear removes all listeners immediately, resetting the EventTarget to its initial state. Existing Subscription handles become no-ops but remain safe to call (they won't panic or corrupt state).
func (*EventTarget[T]) Dispatch ¶
func (et *EventTarget[T]) Dispatch(ev T) bool
Dispatch invokes all active listeners for the given event.
The dispatch mode (sync vs async) is determined by the event type:
- Synchronous dispatch if the event implements Stoppable (StopPropagation)
- Synchronous dispatch if the event implements IsSynchronous() returning true
- Asynchronous dispatch otherwise (listeners run concurrently)
Synchronous dispatch guarantees deterministic execution order and supports StopPropagation to halt further listener invocation.
Returns false if the event implements Cancelable and DefaultPrevented() returns true after all handlers have run.
func (*EventTarget[T]) Len ¶
func (et *EventTarget[T]) Len() int
Len returns the count of currently active (non-tombstoned) listeners.
type Listener ¶
type Listener[T any] func(T)
Listener is a callback function that receives an event payload of type T. Use pointer types (*MyEvent) if handlers need to mutate the event, such as calling PreventDefault on a cancelable event.
type PanicHandler ¶
type PanicHandler func(recovered any)
PanicHandler is a callback function invoked when a listener panics and RecoverPanic is enabled. It receives the recovered panic value. The handler must be safe for concurrent calls when using async dispatch.
type Stoppable ¶
type Stoppable interface {
// StopPropagation prevents any further listeners from being called.
StopPropagation()
// PropagationStopped returns true if StopPropagation was called.
PropagationStopped() bool
}
Stoppable is implemented by events that support StopPropagation semantics. When propagation is stopped, no further listeners will be invoked. Events implementing this interface are always dispatched synchronously since stopping propagation only makes sense with ordered execution.
type Subscription ¶
type Subscription struct {
// contains filtered or unexported fields
}
Subscription is a handle returned when registering a listener. It provides a safe way to unsubscribe from events. The Unsubscribe method is idempotent - calling it multiple times has no additional effect.
func (*Subscription) Unsubscribe ¶
func (s *Subscription) Unsubscribe()
Unsubscribe removes the associated listener from the EventTarget. Safe to call multiple times; subsequent calls are no-ops.
type Synchronous ¶
type Synchronous struct{}
Synchronous can be embedded in event types to force synchronous dispatch. This is useful when handler execution order matters but you don't need the full StopPropagation capability.
Example:
type OrderedEvent struct {
evobs.Synchronous
Data string
}
func (Synchronous) IsSynchronous ¶
func (Synchronous) IsSynchronous() bool
IsSynchronous returns true, indicating this event requires synchronous dispatch.