sum

package module
v0.0.11 Latest Latest
Warning

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

Go to latest
Published: Mar 26, 2026 License: MIT Imports: 18 Imported by: 0

README

sum

CI Status codecov Go Report Card CodeQL Go Reference License Go Version Release

Wire once, run anywhere. An application framework that unifies HTTP, data, configuration, and services into a single lifecycle.

Compose and Run

// Register services by contract type
k := sum.Start()
sum.Register[UserService](k, &userImpl{})
sum.Register[OrderService](k, &orderImpl{})
sum.Freeze(k)

// Retrieve anywhere by type
userSvc := sum.MustUse[UserService](ctx)

Services, configuration, and data stores—all wired through one registry, resolved by type.

Install

go get github.com/zoobz-io/sum

Requires Go 1.24 or later.

Quick Start

package main

import (
    "context"
    "log"

    "github.com/zoobz-io/sum"
)

type Greeter interface {
    Greet(name string) string
}

type greeterImpl struct{}

func (g *greeterImpl) Greet(name string) string {
    return "Hello, " + name
}

func main() {
    // Initialize service and registry
    svc := sum.New(sum.ServiceConfig{Host: "localhost", Port: 8080})
    k := sum.Start()

    // Register services
    sum.Register[Greeter](k, &greeterImpl{})
    sum.Freeze(k)

    // Use services anywhere
    greeter := sum.MustUse[Greeter](context.Background())
    log.Println(greeter.Greet("World"))

    // Run with graceful shutdown
    if err := svc.Run(); err != nil {
        log.Fatal(err)
    }
}

Capabilities

Capability Description Documentation
Service Registry Type-safe service locator with guards Registry
Lifecycle Management Singleton service with graceful shutdown Service
Configuration Load and register config via fig Config
Typed Events Emit and listen with type-safe payloads Event
Data Stores Database, KV, and object storage helpers Database

Why sum?

  • Type-safe service registry — Register and retrieve services by contract type, not strings. Compile-time safety, zero casting.
  • Unified lifecycle — One Run() handles startup, signal handling, and graceful shutdown.
  • Integrated data catalog — Databases, KV stores, and buckets register automatically with the data catalog for observability.
  • Typed events — Define events once with Event[T], emit and listen with full type safety.
  • Minimal ceremony — No annotations, no reflection magic, no code generation. Just Go.

The Ecosystem

sum builds on the zoobz-io toolkit:

Package Purpose
rocco HTTP engine with OpenAPI
slush Service registry core
capitan Event/signal system
fig Configuration loading
grub Database/KV/Object storage
scio Data catalog

Documentation

Contributing

Contributions welcome—see CONTRIBUTING.md for guidelines.

License

MIT License - see LICENSE

Documentation

Overview

Package sum provides an applications framework for Go.

Index

Constants

This section is empty.

Variables

View Source
var (
	Emit  = capitan.Emit
	Debug = capitan.Debug
	Info  = capitan.Info
	Warn  = capitan.Warn
	Error = capitan.Error
)

Emission function re-exports.

View Source
var (
	NewStringKey   = capitan.NewStringKey
	NewIntKey      = capitan.NewIntKey
	NewInt64Key    = capitan.NewInt64Key
	NewFloat64Key  = capitan.NewFloat64Key
	NewBoolKey     = capitan.NewBoolKey
	NewTimeKey     = capitan.NewTimeKey
	NewDurationKey = capitan.NewDurationKey
	NewErrorKey    = capitan.NewErrorKey
)

Field key constructor re-exports.

View Source
var (
	ErrNotFound     = slush.ErrNotFound
	ErrAccessDenied = slush.ErrAccessDenied
	ErrInvalidKey   = slush.ErrInvalidKey
)

Error re-exports from slush.

View Source
var (
	SignalRegistered capitan.Signal = slush.SignalRegistered
	SignalAccessed   capitan.Signal = slush.SignalAccessed
	SignalDenied     capitan.Signal = slush.SignalDenied
	SignalNotFound   capitan.Signal = slush.SignalNotFound
)

Signal re-exports from slush.

View Source
var (
	KeyInterface capitan.Key = slush.KeyInterface
	KeyImpl      capitan.Key = slush.KeyImpl
	KeyError     capitan.Key = slush.KeyError
)

Field key re-exports from slush.

View Source
var ErrTokenRequired = fmt.Errorf("token required")

ErrTokenRequired indicates a service requires a token but none was provided.

View Source
var NewSignal = capitan.NewSignal

NewSignal creates a signal with name and description.

Functions

func Config

func Config[T any](ctx context.Context, k Key, provider fig.SecretProvider) error

Config loads configuration of type T via fig and registers it with the service locator. Pass nil for provider if secrets are not needed. Retrieve the configuration later with Use[T](ctx).

func Freeze

func Freeze(k Key)

Freeze prevents further service registration. Panics if key is invalid.

func MustUse

func MustUse[T any](ctx context.Context) T

MustUse retrieves a service by its contract type T. Panics if the service is not registered or a guard fails.

func Use

func Use[T any](ctx context.Context) (T, error)

Use retrieves a service by its contract type T. Runs all registered guards with the provided context. Returns ErrNotFound if not registered, ErrAccessDenied if a guard fails.

func WithToken

func WithToken(ctx context.Context, t Token) context.Context

WithToken injects a token into the context.

Types

type Boundary

type Boundary[T any] interface {
	Send(ctx context.Context, obj T) (T, error)
	Receive(ctx context.Context, obj T) (T, error)
	Store(ctx context.Context, obj T) (T, error)
	Load(ctx context.Context, obj T) (T, error)
}

Boundary defines the serialization lifecycle operations for a type.

func NewBoundary

func NewBoundary[T cereal.Cloner[T]](k Key) Boundary[T]

NewBoundary creates a Boundary[T], applies shared capabilities from the Service, and registers it in the service registry under the given key. Panics if cereal.NewProcessor fails (structurally unreachable for valid Cloner types).

type Bucket

type Bucket[M any] struct {
	*grub.Bucket[M]
}

Bucket wraps grub.Bucket and registers with scio on creation. Embed this type in your store structs to add custom methods.

func NewBucket

func NewBucket[M any](provider grub.BucketProvider, name string) (*Bucket[M], error)

NewBucket creates a Bucket[M] and registers it with the scio catalog. Requires sum.New() to have been called first.

type Codec

type Codec = cereal.Codec

Codec is a re-export of cereal.Codec.

type Database

type Database[M any] struct {
	*grub.Database[M]
}

Database wraps grub.Database and registers with scio on creation. Embed this type in your store structs to add custom query methods.

func NewDatabase

func NewDatabase[M any](db *sqlx.DB, table string, renderer astql.Renderer) (*Database[M], error)

NewDatabase creates a Database[M] and registers it with the scio catalog. Requires sum.New() to have been called first.

type EncryptAlgo

type EncryptAlgo = cereal.EncryptAlgo

EncryptAlgo is a re-export of cereal.EncryptAlgo.

type Encryptor

type Encryptor = cereal.Encryptor

Encryptor is a re-export of cereal.Encryptor.

type Event

type Event[T any] struct {
	// Signal is the underlying capitan signal.
	Signal capitan.Signal

	// Key is the typed key for extracting event data.
	Key capitan.GenericKey[T]
	// contains filtered or unexported fields
}

Event provides bidirectional access to a signal with typed data. Use Emit to dispatch events and Listen to register callbacks.

func NewDebugEvent

func NewDebugEvent[T any](signal capitan.Signal) Event[T]

NewDebugEvent creates an Event that emits at Debug level.

func NewErrorEvent

func NewErrorEvent[T any](signal capitan.Signal) Event[T]

NewErrorEvent creates an Event that emits at Error level.

func NewEvent

func NewEvent[T any](signal capitan.Signal, level capitan.Severity) Event[T]

NewEvent creates an Event with the given signal and severity level. The variant is derived automatically from T via sentinel.

func NewInfoEvent

func NewInfoEvent[T any](signal capitan.Signal) Event[T]

NewInfoEvent creates an Event that emits at Info level.

func NewWarnEvent

func NewWarnEvent[T any](signal capitan.Signal) Event[T]

NewWarnEvent creates an Event that emits at Warn level.

func (Event[T]) Emit

func (e Event[T]) Emit(ctx context.Context, data T)

Emit dispatches an event with the configured severity level.

func (Event[T]) Listen

func (e Event[T]) Listen(callback func(context.Context, T)) *capitan.Listener

Listen registers a callback for this event. Returns a Listener that can be closed to unregister.

func (Event[T]) ListenOnce

func (e Event[T]) ListenOnce(callback func(context.Context, T)) *capitan.Listener

ListenOnce registers a callback that fires only once, then automatically unregisters. Returns a Listener that can be closed early to prevent the callback from firing.

type Guard

type Guard = slush.Guard

Guard is a validation function that permits or denies service access.

func Require

func Require(tokens ...Token) Guard

Require returns a guard that checks for any of the provided tokens. If the service has Require, the context must contain a matching token.

type Handle

type Handle[T any] struct {
	*slush.Handle[T]
}

Handle configures a registered service with optional guards. Wraps slush.Handle to provide sum-specific conveniences.

func Register

func Register[T any](k Key, impl T) *Handle[T]

Register registers a service implementation for the contract type T. Returns a Handle for optional guard configuration. Panics if Start has not been called, key is invalid, or registry is frozen.

func (*Handle[T]) For

func (h *Handle[T]) For(tokens ...Token) *Handle[T]

For restricts service access to contexts bearing any of the provided tokens. Equivalent to Guard(Require(tokens...)).

func (*Handle[T]) Guard

func (h *Handle[T]) Guard(g Guard) *Handle[T]

Guard adds a custom guard function to the service. Returns the Handle for chaining.

type HashAlgo

type HashAlgo = cereal.HashAlgo

HashAlgo is a re-export of cereal.HashAlgo.

type Hasher

type Hasher = cereal.Hasher

Hasher is a re-export of cereal.Hasher.

type Key

type Key = slush.Key

Key grants the capability to register services.

func Start

func Start() Key

Start initializes the service registry and returns a Key for registration. Panics if called more than once.

type MaskType

type MaskType = cereal.MaskType

MaskType is a re-export of cereal.MaskType.

type Masker

type Masker = cereal.Masker

Masker is a re-export of cereal.Masker.

type Search[M any] struct {
	*grub.Search[M]
}

Search wraps grub.Search and registers with scio on creation. Embed this type in your store structs to add custom query methods.

func NewSearch

func NewSearch[M any](provider grub.SearchProvider, index string) (*Search[M], error)

NewSearch creates a Search[M] and registers it with the scio catalog. Requires sum.New() to have been called first.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service wraps a rocco engine and scio catalog, providing application lifecycle.

func New

func New() *Service

New creates or returns the singleton Service. Subsequent calls return the existing instance.

func (*Service) Catalog

func (s *Service) Catalog() *scio.Scio

Catalog returns the scio data catalog for advanced usage.

func (*Service) Engine

func (s *Service) Engine() *rocco.Engine

Engine returns the underlying rocco engine for advanced usage.

func (*Service) Handle

func (s *Service) Handle(endpoints ...rocco.Endpoint)

Handle registers endpoints with the underlying engine.

func (*Service) Run

func (s *Service) Run(host string, port int) error

Run starts the service and blocks until a shutdown signal is received. Handles SIGINT and SIGTERM, then performs graceful shutdown with a 30 second timeout.

func (*Service) Shutdown

func (s *Service) Shutdown(ctx context.Context) error

Shutdown gracefully stops the service.

func (*Service) Start

func (s *Service) Start(host string, port int) error

Start begins serving. This method blocks until shutdown.

func (*Service) Tag

func (s *Service) Tag(name, description string)

Tag registers an OpenAPI tag with a description.

func (*Service) WithCodec

func (s *Service) WithCodec(codec cereal.Codec) *Service

WithCodec sets the default codec for cereal processors and the rocco engine.

func (*Service) WithEncryptor

func (s *Service) WithEncryptor(algo cereal.EncryptAlgo, enc cereal.Encryptor) *Service

WithEncryptor registers an encryptor for the given algorithm.

func (*Service) WithHasher

func (s *Service) WithHasher(algo cereal.HashAlgo, h cereal.Hasher) *Service

WithHasher registers a hasher for the given algorithm.

func (*Service) WithMasker

func (s *Service) WithMasker(mt cereal.MaskType, m cereal.Masker) *Service

WithMasker registers a masker for the given mask type.

type ServiceInfo

type ServiceInfo = slush.ServiceInfo

ServiceInfo describes a registered service for enumeration.

func Services

func Services(k Key) ([]ServiceInfo, error)

Services returns information about all registered services. Returns ErrInvalidKey if the key is invalid.

type Severity

type Severity = capitan.Severity

Severity is the importance level of an emission.

type Signal

type Signal = capitan.Signal

Signal is a named event identifier.

type Store

type Store[M any] struct {
	*grub.Store[M]
}

Store wraps grub.Store and registers with scio on creation. Embed this type in your store structs to add custom methods.

func NewStore

func NewStore[M any](provider grub.StoreProvider, name string) (*Store[M], error)

NewStore creates a Store[M] and registers it with the scio catalog. Requires sum.New() to have been called first.

type Token

type Token struct {
	// contains filtered or unexported fields
}

Token is an unforgeable capability for service access.

func NewToken

func NewToken(name string) Token

NewToken creates a new access token with the given name.

func (Token) String

func (t Token) String() string

String returns the token name for debugging.

Jump to

Keyboard shortcuts

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