reactive

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 11, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var TrackingStack []*trackingFrame

TrackingStack is the package-level dependency tracking stack.

Functions

func ArrayMap

func ArrayMap[T, U any](a *Array[T], fn func(T) U) []U

ArrayMap transforms each element of a using fn and returns a plain []U. The result is not reactive.

func ArrayReduce

func ArrayReduce[T, U any](a *Array[T], fn func(U, T) U, init U) U

ArrayReduce folds a into a single value of type U using fn, starting from init.

func ArraySort

func ArraySort[T cmp.Ordered](a *Array[T])

ArraySort sorts a in ascending order. T must satisfy cmp.Ordered.

func ArraySortDesc

func ArraySortDesc[T cmp.Ordered](a *Array[T])

ArraySortDesc sorts a in descending order. T must satisfy cmp.Ordered.

func ArraySortFold

func ArraySortFold[T any](a *Array[T], key func(T) string)

ArraySortFold sorts a case-insensitively using key to extract a string from each element. Comparison uses Unicode simple case-folding so "Abc" == "abc" == "ABC".

func BindFormatter

func BindFormatter[T comparable](source *Ref[T]) (*Ref[string], WatchHandle)

BindFormatter returns a *Ref[string] that stays in sync with source, converting values via fmt.Sprint.

The returned WatchHandle must be stopped when the binding is no longer needed (e.g. via screen.TrackRef or an explicit h.Stop() call). Dropping the handle leaks a watcher on source for the lifetime of source.

func BindFormatterf

func BindFormatterf[T comparable](source *Ref[T], format string) (*Ref[string], WatchHandle)

BindFormatterf returns a *Ref[string] that stays in sync with source, converting values via fmt.Sprintf with the given format string.

The returned WatchHandle must be stopped when the binding is no longer needed (e.g. via screen.TrackRef or an explicit h.Stop() call). Dropping the handle leaks a watcher on source for the lifetime of source.

func Includes

func Includes[T comparable](a *Array[T], item T) bool

Includes reports whether item is present in a. T must be comparable.

func Increment

func Increment[T Numeric](r *Ref[T], delta T) func()

Increment returns a func() that adds delta to the ref's value.

func IndexOf

func IndexOf[T comparable](a *Array[T], item T) int

IndexOf returns the index of item in a, or -1 if absent. T must be comparable.

func Set

func Set[T comparable](r *Ref[T], val T) func()

Set returns a func() that sets the ref to the given value.

func Toggle

func Toggle(r *Ref[bool]) func()

Toggle returns a func() that flips a boolean ref.

Types

type Array

type Array[T any] struct {
	// contains filtered or unexported fields
}

Array[T] is a reactive ordered collection. T is unconstrained (any). Every mutation bumps an internal version counter, notifying all WatchEffect and Computed subscribers through the normal reactive graph. Granular callbacks (OnAdded, OnRemoved, OnMoved, OnReplaced) carry operation detail for incremental or animated widget updates.

Array implements reactiveSource directly — no intermediate *Ref allocation. bumpVersion is a no-op when there are no reactive subscribers (common case).

func NewArray

func NewArray[T any]() *Array[T]

NewArray creates an empty reactive array.

func NewArrayFrom

func NewArrayFrom[T any](items []T) *Array[T]

NewArrayFrom creates a reactive array from an existing slice. The input slice is copied — the caller retains ownership of the original.

func NewArrayFromAny

func NewArrayFromAny[T any](items []T) *Array[any]

NewArrayFromAny creates a reactive Array[any] from a typed slice, boxing each element. This avoids the need for callers to manually convert []T to []any.

func NewArrayWithCap

func NewArrayWithCap[T any](cap int) *Array[T]

NewArrayWithCap creates an empty reactive array with the given initial capacity.

func (*Array[T]) At

func (a *Array[T]) At(i int) T

At returns the element at index i. Supports negative indexing (At(-1) = last). Panics if out of bounds.

func (*Array[T]) Batch

func (a *Array[T]) Batch(fn func())

Batch groups multiple mutations into a single notification. The outermost Batch controls the single notification; inner Batch calls while batching is already active run fn immediately without re-batching.

func (*Array[T]) Clear

func (a *Array[T]) Clear()

Clear removes all elements.

func (*Array[T]) Clone

func (a *Array[T]) Clone() *Array[T]

Clone returns a new Array with the same contents.

func (*Array[T]) Concat

func (a *Array[T]) Concat(others ...*Array[T]) *Array[T]

Concat returns a new Array with all elements from a followed by all elements from others.

func (*Array[T]) Every

func (a *Array[T]) Every(fn func(T) bool) bool

Every returns true if all elements satisfy fn (vacuously true for empty).

func (*Array[T]) Fill

func (a *Array[T]) Fill(v T, start, end int)

Fill sets elements in [start, end) to v.

func (*Array[T]) Filter

func (a *Array[T]) Filter(fn func(T) bool) *Array[T]

Filter returns a new Array containing elements that satisfy fn.

func (*Array[T]) Find

func (a *Array[T]) Find(fn func(T) bool) (T, bool)

Find returns the first element satisfying fn, and true. Returns zero, false if not found.

func (*Array[T]) FindIndex

func (a *Array[T]) FindIndex(fn func(T) bool) int

FindIndex returns the index of the first element satisfying fn, or -1.

func (*Array[T]) ForEach

func (a *Array[T]) ForEach(fn func(i int, v T))

ForEach calls fn for each element with its index.

func (*Array[T]) Insert

func (a *Array[T]) Insert(i int, item T)

Insert inserts item at index i, shifting existing elements right.

func (*Array[T]) Len

func (a *Array[T]) Len() int

Len returns the number of elements and registers a reactive dependency.

func (*Array[T]) LenRef

func (a *Array[T]) LenRef() *Ref[int]

LenRef returns a *Ref[int] that reactively tracks the array's length. The Ref is allocated lazily on first call and kept in sync by bumpVersion. Because Ref.Set is a no-op when the value is unchanged, length-preserving mutations (SetAt, Swap, Sort, Reverse, …) never propagate through it.

func (*Array[T]) Move

func (a *Array[T]) Move(from, to int)

Move moves the element at from to index to. Elements between from and to shift one position to fill the gap.

[A, B, C, D]  Move(0, 2) → [B, C, A, D]
[A, B, C, D]  Move(2, 0) → [C, A, B, D]

func (*Array[T]) OnAdded

func (a *Array[T]) OnAdded(fn func(index int, item T)) WatchHandle

OnAdded registers a callback that fires when elements are added.

func (*Array[T]) OnChange

func (a *Array[T]) OnChange(fn func()) WatchHandle

OnChange registers a callback that fires after every mutation. Returns a WatchHandle — call Stop() to unsubscribe.

func (*Array[T]) OnItemChanged

func (a *Array[T]) OnItemChanged(fn func(index int, item T)) WatchHandle

OnItemChanged registers a callback that fires when a single item is updated in-place via SetAt.

func (*Array[T]) OnMoved

func (a *Array[T]) OnMoved(fn func(from, to int)) WatchHandle

OnMoved registers a callback that fires when an element is moved.

func (*Array[T]) OnRemoved

func (a *Array[T]) OnRemoved(fn func(index int, item T)) WatchHandle

OnRemoved registers a callback that fires when elements are removed.

func (*Array[T]) OnReplaced

func (a *Array[T]) OnReplaced(fn func()) WatchHandle

OnReplaced registers a callback that fires when the array is restructured.

func (*Array[T]) Pop

func (a *Array[T]) Pop() T

Pop removes and returns the last element. Panics if empty.

func (*Array[T]) Push

func (a *Array[T]) Push(items ...T)

Push appends one or more items to the end.

func (*Array[T]) RandomItem

func (a *Array[T]) RandomItem() (T, bool)

RandomItem returns a random element, or zero/false if empty.

func (*Array[T]) Remove

func (a *Array[T]) Remove(i int)

Remove removes the element at index i.

func (*Array[T]) RemoveAt

func (a *Array[T]) RemoveAt(i int)

RemoveAt removes the element at index i (alias for Remove).

func (*Array[T]) Reserve

func (a *Array[T]) Reserve(n int)

Reserve ensures the underlying slice has at least n capacity.

func (*Array[T]) Reverse

func (a *Array[T]) Reverse()

Reverse reverses the array in place.

func (*Array[T]) Set

func (a *Array[T]) Set(items []T)

Set replaces all contents with the provided slice (copied).

func (*Array[T]) SetAt

func (a *Array[T]) SetAt(index int, item T)

SetAt replaces the item at index in-place and fires OnItemChanged. Panics if index is out of range.

func (*Array[T]) Shift

func (a *Array[T]) Shift() T

Shift removes and returns the first element. Panics if empty.

func (*Array[T]) Shrink

func (a *Array[T]) Shrink()

Shrink reallocates the underlying slice to exactly fit its contents.

func (*Array[T]) Shuffle

func (a *Array[T]) Shuffle()

Shuffle randomizes the order of elements using Fisher-Yates.

func (*Array[T]) Slice

func (a *Array[T]) Slice(start, end int) []T

Slice returns a copy of elements [start, end) and registers a reactive dependency.

func (*Array[T]) Some

func (a *Array[T]) Some(fn func(T) bool) bool

Some returns true if any element satisfies fn.

func (*Array[T]) Sort

func (a *Array[T]) Sort(less func(T, T) int)

Sort sorts the array using the provided less-than function.

func (*Array[T]) Splice

func (a *Array[T]) Splice(start, del int, items ...T)

Splice removes del elements starting at start, then inserts items. Fires OnRemoved (remove-only), OnAdded (insert-only), or OnReplaced (both).

func (*Array[T]) Swap

func (a *Array[T]) Swap(i, j int)

Swap swaps the elements at indices i and j. Fires OnMoved once with (i, j) to signal the swap.

func (*Array[T]) Truncate

func (a *Array[T]) Truncate(n int)

Truncate keeps only the first n elements.

func (*Array[T]) Unshift

func (a *Array[T]) Unshift(items ...T)

Unshift prepends one or more items to the front.

func (*Array[T]) Version

func (a *Array[T]) Version() *Ref[uint64]

Version returns a *Ref[uint64] that mirrors the array's version counter, for use with WatchValue. The Ref is allocated lazily on first call.

type Computed

type Computed[T comparable] struct {
	// contains filtered or unexported fields
}

Computed derives a value from reactive dependencies. It re-evaluates lazily: the function is only called on the next Get() after the node has been marked dirty.

func NewComputed

func NewComputed[T comparable](fn func() T) *Computed[T]

NewComputed creates a new Computed that derives its value by calling fn. The function is evaluated eagerly once to establish initial dependencies.

func (*Computed[T]) Get

func (c *Computed[T]) Get() T

Get returns the current value, re-evaluating if dirty. It also registers a dependency if called inside another Computed or Watch evaluation.

func (*Computed[T]) Peek

func (c *Computed[T]) Peek() T

Peek returns the current cached value without registering a dependency and without re-evaluating even if dirty.

type Numeric

type Numeric interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~float32 | ~float64
}

Numeric is a constraint for types that support arithmetic operations.

type Record

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

Record is a reactive key-value object. Each field is stored as a *Ref[any] so that WatchEffect and Computed callers tracking a specific field are not disturbed by unrelated field changes.

Record is not goroutine-safe — all mutations must occur on the game-loop goroutine.

func NewRecord

func NewRecord() *Record

NewRecord creates an empty Record.

func NewRecordFrom

func NewRecordFrom(fields map[string]any) *Record

NewRecordFrom creates a Record pre-populated with fields. The map is copied — the caller retains ownership of the original.

func (*Record) Delete

func (r *Record) Delete(key string)

Delete removes key from the record and fires OnChange with a nil value.

func (*Record) Get

func (r *Record) Get(key string) any

Get returns the current value for key, or nil if the key is not set. Registers a reactive dependency when called inside a WatchEffect or Computed.

func (*Record) Has

func (r *Record) Has(key string) bool

Has reports whether key exists without creating it.

func (*Record) Keys

func (r *Record) Keys() []string

Keys returns a snapshot of all current keys (order is not guaranteed).

func (*Record) OnChange

func (r *Record) OnChange(fn func(key string, value any)) WatchHandle

OnChange registers a callback that fires when any field changes, passing the key and new value. Returns a WatchHandle — call Stop() to unsubscribe.

func (*Record) OnFieldChange

func (r *Record) OnFieldChange(key string, fn func(value any)) WatchHandle

OnFieldChange registers a callback that fires when the named field changes. The callback does NOT fire on registration — only on subsequent changes. Returns a WatchHandle — call Stop() to unsubscribe.

func (*Record) Ref

func (r *Record) Ref(key string) *Ref[any]

Ref returns the internal *Ref[any] for key, creating the field with a nil value if it does not yet exist. Use inside WatchEffect or Computed to track a specific field reactively.

func (*Record) Set

func (r *Record) Set(key string, value any)

Set assigns value to key, creating the field if it doesn't exist. Fires onChange callbacks only when the value actually changes.

func (*Record) SetMany

func (r *Record) SetMany(fields map[string]any)

SetMany assigns multiple fields. OnChange fires once per changed field.

func (*Record) ToMap

func (r *Record) ToMap() map[string]any

ToMap returns a snapshot copy of all fields as a plain map. Mutations to the returned map do not affect the Record.

type Ref

type Ref[T comparable] struct {
	// contains filtered or unexported fields
}

Ref holds a single reactive value of type T. When the value changes, all subscribers (Computed nodes and Watches) are marked dirty and enqueued for the next scheduler flush.

func NewRef

func NewRef[T comparable](initial T) *Ref[T]

NewRef creates a new Ref with the given initial value.

func (*Ref[T]) Get

func (r *Ref[T]) Get() T

Get returns the current value and registers a dependency if called inside a Computed or Watch evaluation.

func (*Ref[T]) Peek

func (r *Ref[T]) Peek() T

Peek returns the current value without registering a dependency.

func (*Ref[T]) Set

func (r *Ref[T]) Set(v T)

Set updates the value. If the new value equals the old value, this is a no-op. Otherwise, all subscribers are marked dirty and enqueued on the default scheduler.

func (*Ref[T]) Update

func (r *Ref[T]) Update(fn func(T) T)

Update applies fn to the current value and sets the result. This is shorthand for r.Set(fn(r.Peek())).

type Scheduler

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

Scheduler batches reactive updates and flushes them once per frame.

var DefaultScheduler Scheduler

DefaultScheduler is the package-level scheduler instance used by all reactive primitives. Call DefaultScheduler.Flush() once per frame before the UI update pass.

func (*Scheduler) Enqueue

func (s *Scheduler) Enqueue(f flushable)

Enqueue adds a flushable to the dirty set for the next flush. Duplicates are allowed; flush uses a generation counter to skip nodes that have already been processed.

func (*Scheduler) Flush

func (s *Scheduler) Flush()

Flush processes all enqueued dirty nodes. Computeds are flushed before watches so that watch callbacks observe up-to-date values. This should be called once per frame before the UI update pass.

type WatchHandle

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

WatchHandle allows stopping a watch subscription.

func WatchEffect

func WatchEffect(fn func()) WatchHandle

WatchEffect creates a watch that re-runs fn whenever any reactive value accessed inside fn changes. The function is run once immediately to establish initial dependencies.

func WatchValue

func WatchValue[T comparable](ref *Ref[T], fn func(old, new T)) WatchHandle

WatchValue watches a specific Ref and calls fn with the old and new values. The callback fires immediately with (current, current) to prime the initial state, then with (old, new) on each subsequent change.

func (WatchHandle) Stop

func (h WatchHandle) Stop()

Stop removes all subscriptions and prevents the watch from firing again.

Jump to

Keyboard shortcuts

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