evobs

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 21, 2026 License: 0BSD Imports: 4 Imported by: 0

README

evobs

A type-safe, generic event bus for Go inspired by the DOM EventTarget API.

Installation

go get -u codeberg.org/0x5a17ed/evobs

Usage

package main

import "codeberg.org/0x5a17ed/evobs"

type MyEvent struct {
    Message string
}

func main() {
    target := &evobs.EventTarget[MyEvent]{}

    sub := target.Add(func(ev MyEvent) {
        println(ev.Message)
    })

    target.Dispatch(MyEvent{Message: "hello"})

    sub.Unsubscribe()
}

License

BSD0

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

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

func (b *BaseEvent) DefaultPrevented() bool

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL