Documentation
¶
Overview ¶
Package loom implements a reactive functional programming framework built on seven primitives: ref, derived, watch, action, pattern, for, apply.
The entire runtime is one function:
func step(env Env, action Action) Env {
if !action.Permits(env) { return env }
rebinds := action.Effect(env)
newEnv := env.Apply(rebinds)
watches := fireWatches(env, newEnv)
return fold(newEnv, watches)
}
Index ¶
- func Bool(v any) bool
- func Float(v any) float64
- func Int(v any) int
- func Slice(v any) []any
- func String(v any) string
- type Action
- type ActionFunc
- type ApplyFn
- type DerivedDecl
- type DerivedFn
- type Env
- func (e Env) Apply(rebinds []Rebind) Env
- func (e Env) Diff(other Env) []Rebind
- func (e Env) Get(key string) any
- func (e Env) GetOr(key string, def any) any
- func (e Env) Has(key string) bool
- func (e Env) Length(prefix string) int
- func (e Env) Namespace(prefix string) map[string]any
- func (e Env) Set(key string, value any) Env
- func (e Env) Snapshot() Env
- func (e Env) String() string
- func (e Env) ToMap() map[string]any
- type Event
- type ForFn
- type InvariantDecl
- type InvariantError
- type InvariantFn
- type InvariantViolation
- type Loom
- func (l *Loom) Action(name string, action Action) *Loom
- func (l *Loom) Build() *Runtime
- func (l *Loom) Derived(key string, fn DerivedFn) *Loom
- func (l *Loom) Invariant(name string, fn InvariantFn) *Loom
- func (l *Loom) Module(m Module) *Loom
- func (l *Loom) OnSignal(signal string, fn OnSignalFn) *Loom
- func (l *Loom) Pattern(name string, fn PatternFn) *Loom
- func (l *Loom) Ref(key string, value any) *Loom
- func (l *Loom) Refs(decls ...RefDecl) *Loom
- func (l *Loom) Selector(name string, pattern string) *Loom
- func (l *Loom) Watch(pattern string, fn WatchFn) *Loom
- func (l *Loom) WithTelemetry(options TelemetryOptions) *Loom
- type Module
- type OnSignalFn
- type PatternFn
- type PermitError
- type Rebind
- type RefDecl
- type Registry
- func (r *Registry) AddAction(name string, action Action)
- func (r *Registry) AddDerived(key string, name string, fn DerivedFn)
- func (r *Registry) AddInvariant(name string, fn InvariantFn)
- func (r *Registry) AddPattern(name string, fn PatternFn)
- func (r *Registry) AddRef(key string, value any)
- func (r *Registry) AddSelector(name string, pattern string)
- func (r *Registry) AddSignal(signal string, name string, fn OnSignalFn)
- func (r *Registry) AddWatch(pattern string, name string, fn WatchFn)
- func (r *Registry) Merge(other *Registry)
- type Runtime
- func (rt *Runtime) Dispatch(name string, args map[string]any) error
- func (rt *Runtime) DispatchContext(ctx context.Context, name string, args map[string]any) (err error)
- func (rt *Runtime) Emit(name string, args map[string]any) error
- func (rt *Runtime) EmitContext(ctx context.Context, name string, args map[string]any) error
- func (rt *Runtime) EventLog() []Event
- func (rt *Runtime) Get(key string) any
- func (rt *Runtime) GetOr(key string, def any) any
- func (rt *Runtime) History() []Env
- func (rt *Runtime) Length(prefix string) int
- func (rt *Runtime) Namespace(prefix string) map[string]any
- func (rt *Runtime) Replay(events []Event) error
- func (rt *Runtime) Select(name string) map[string]any
- func (rt *Runtime) Snapshot() Env
- type SelectorDecl
- type Signal
- type SignalDecl
- type SpreadRange
- type StateView
- type TelemetryOptions
- type WatchDecl
- type WatchFn
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Action ¶
type Action interface {
Permits(state StateView, args map[string]any) bool
Effect(state StateView, args map[string]any) []Rebind
}
Action is a permitted state transition. Permits() is a pure guard. Effect() returns descriptions of changes, never executes them.
type ActionFunc ¶
type ActionFunc struct {
// contains filtered or unexported fields
}
ActionFunc is a convenience Action from two functions.
type DerivedDecl ¶
DerivedDecl binds a key to a DerivedFn.
type Env ¶
type Env struct {
// contains filtered or unexported fields
}
Env is an immutable snapshot of the ref graph. Every Rebind produces a new Env. History is a slice of Envs — free, because immutable.
type Event ¶
Event is a record in the event log. For action events, Action is set and Signal is empty. For signal events, Signal is set and Action is empty.
type InvariantDecl ¶
type InvariantDecl struct {
Name string
Fn InvariantFn
}
InvariantDecl binds a name to an InvariantFn.
type InvariantError ¶
type InvariantError struct {
Violations []InvariantViolation
}
InvariantError is returned when one or more invariants are violated after a dispatch or signal emission settles.
func (InvariantError) Error ¶
func (e InvariantError) Error() string
type InvariantFn ¶
InvariantFn is a global rule evaluated on settled state after each dispatch or signal emission. Return nil or an empty slice for success; return errors to signal violations.
type InvariantViolation ¶
InvariantViolation holds a single invariant failure.
type Loom ¶
type Loom struct {
// contains filtered or unexported fields
}
Loom assembles declarations into a Runtime.
l := loom.New()
l.Ref("game.state", "active")
l.Action("attack", AttackAction{})
l.Watch("player.*.life", onLifeChange)
rt := l.Build()
rt.Dispatch("attack", map[string]any{"target": "bob", "amount": 5})
func (*Loom) Invariant ¶
func (l *Loom) Invariant(name string, fn InvariantFn) *Loom
Invariant registers a global rule evaluated on settled state after each dispatch or signal emission. Dispatch fails if any invariant returns errors.
func (*Loom) OnSignal ¶
func (l *Loom) OnSignal(signal string, fn OnSignalFn) *Loom
OnSignal registers a handler for the named signal. Handlers may return rebinds that cascade through the normal watch/derived chain.
func (*Loom) Selector ¶
Selector registers a named, reusable scope over refs identified by pattern. The pattern uses the same dot-separated glob syntax as Watch patterns.
func (*Loom) WithTelemetry ¶
func (l *Loom) WithTelemetry(options TelemetryOptions) *Loom
WithTelemetry configures OpenTelemetry integration for runtimes built from this Loom instance.
type Module ¶
type Module interface {
Register() *Registry
}
Module is the unit of organization in Loom. A game, a service, or a domain is a Module. Modules return a Registry of their declarations.
type OnSignalFn ¶
OnSignalFn handles an emitted signal and may return rebinds.
type PermitError ¶
type PermitError struct {
Action string
}
PermitError is returned when an action's Permits() returns false.
func (PermitError) Error ¶
func (e PermitError) Error() string
type Rebind ¶
Rebind is a description of a state change. Actions return []Rebind — they never mutate directly.
type RefDecl ¶
RefDecl is a ref declaration at init time.
func Chain ¶
Chain generates linked ref pairs from a sequence.
Chain("turn.after", []string{"alice", "bob", "carol"}, true)
→ turn.after.alice=bob, turn.after.bob=carol, turn.after.carol=alice
type Registry ¶
type Registry struct {
Refs []RefDecl
Derived []DerivedDecl
Watches []WatchDecl
Actions map[string]Action
Patterns map[string]PatternFn
Invariants []InvariantDecl
Signals []SignalDecl
Selectors map[string]SelectorDecl
}
Registry holds all declarations before the runtime is built. Modules register into a Registry. Loom assembles them into a Runtime.
func NewRegistry ¶
func NewRegistry() *Registry
func (*Registry) AddInvariant ¶
func (r *Registry) AddInvariant(name string, fn InvariantFn)
func (*Registry) AddPattern ¶
func (*Registry) AddSelector ¶
type Runtime ¶
type Runtime struct {
// contains filtered or unexported fields
}
Runtime is the fold.
func (*Runtime) DispatchContext ¶
func (rt *Runtime) DispatchContext(ctx context.Context, name string, args map[string]any) (err error)
DispatchContext runs an action by name with a caller-provided context for telemetry propagation.
func (*Runtime) Emit ¶
Emit fires a named signal into the runtime. Signal handlers may return rebinds; these cascade through the normal watch/derived/invariant chain. The signal is captured in the event log.
func (*Runtime) EmitContext ¶
EmitContext is Emit with a caller-provided context for telemetry propagation.
type SelectorDecl ¶
SelectorDecl is a named, reusable scope over refs. The Pattern uses the same dot-separated glob syntax as Watch patterns.
type Signal ¶
Signal is a first-class occurrence emitted into the runtime. Signals model facts that happened even when no ref changes materially.
type SignalDecl ¶
type SignalDecl struct {
Signal string
Name string
Fn OnSignalFn
}
SignalDecl registers a handler for a named signal.
type SpreadRange ¶
SpreadRange is one axis of a spread.
func IntRange ¶
func IntRange(name string, start, end int) SpreadRange
IntRange creates a SpreadRange for integers [start, end).
func Range ¶
func Range(name string, values ...any) SpreadRange
Range creates a SpreadRange from a slice.
type StateView ¶
type StateView interface {
Get(key string) any
GetOr(key string, def any) any
Has(key string) bool
Namespace(prefix string) map[string]any
Length(prefix string) int
Pattern(name string, args ...any) []Rebind
Rebind(key string, value any) Rebind
Apply(description any) []Rebind
// Select returns all env keys matching the named selector.
Select(name string) map[string]any
}
StateView is the read-only view of the env exposed to Action, Watch, Derived, Invariant, and OnSignal functions.
type TelemetryOptions ¶
type TelemetryOptions struct {
TracerProvider trace.TracerProvider
MeterProvider metric.MeterProvider
InstrumentationName string
}
TelemetryOptions configures OpenTelemetry integration for Loom runtimes.
If providers are nil, Loom uses the global providers from the otel package.