Releases: Eventuous/eventuous-go
Releases · Eventuous/eventuous-go
v0.1.0
Eventuous for Go — v0.1.0
First release of the Go port of Eventuous, a production-grade Event Sourcing library.
What's included
Core module (github.com/eventuous/eventuous-go/core)
- Domain:
Aggregate[S]with fold pattern, Apply, guards (EnsureNew/EnsureExists) - Persistence:
EventReader/EventWriter/EventStoreinterfaces,LoadState,LoadAggregate,StoreAggregate - Serialization:
TypeMap(bidirectional type registry),Codecinterface, JSON implementation - Command services: Functional
Service[S](primary) andAggregateService[S](optional DDD pattern) - Subscriptions:
EventHandlerwith middleware chain (WithConcurrency,WithPartitioning,WithLogging),CheckpointCommitterwith gap detection - Test infrastructure: In-memory store, store conformance test suite, subscription conformance test suite, shared Booking test domain
KurrentDB module (github.com/eventuous/eventuous-go/kurrentdb)
- Full
EventStoreimplementation (append, read forward/backward, delete, truncate) - Catch-up subscriptions (stream + $all) with checkpoint support and auto-reconnect
- Persistent subscriptions (stream + $all) with ack/nack
- Integration tests via testcontainers
OpenTelemetry module (github.com/eventuous/eventuous-go/otel)
TracedCommandHandlerdecorator (tracing spans + duration histogram + error counter)TracingMiddlewarefor subscriptions
Installation
go get github.com/eventuous/eventuous-go/core@v0.1.0
go get github.com/eventuous/eventuous-go/kurrentdb@v0.1.0
go get github.com/eventuous/eventuous-go/otel@v0.1.0Quick example
// Define state + fold
type BookingState struct { ID, RoomID string; Active bool }
func bookingFold(state BookingState, event any) BookingState {
switch e := event.(type) {
case RoomBooked:
return BookingState{ID: e.BookingID, RoomID: e.RoomID, Active: true}
default:
return state
}
}
// Create command service
svc := command.New[BookingState](store, store, bookingFold, BookingState{})
command.On(svc, command.Handler[BookRoom, BookingState]{
Expected: eventuous.IsNew,
Stream: func(cmd BookRoom) eventuous.StreamName { return eventuous.NewStreamName("Booking", cmd.BookingID) },
Act: func(ctx context.Context, state BookingState, cmd BookRoom) ([]any, error) {
return []any{RoomBooked{BookingID: cmd.BookingID, RoomID: cmd.RoomID}}, nil
},
})
result, err := svc.Handle(ctx, BookRoom{BookingID: "123", RoomID: "room-42"})Design principles
- Functional-first — pure functions over OOP, type switch fold over handler registration
- Idiomatic Go — composition over inheritance, middleware chains,
context.Context+ errors - Multi-module — import only what you need, no transitive dependency bloat