Documentation
¶
Overview ¶
Package nodra is a state library for MyGo apps: concurrency-safe reactive stores whose snapshots drive native MyGo views. Invalidate redraws a window when its store publishes; the Store itself does not depend on a running MyGo app, so services and tests can use it as well.
Index ¶
- Variables
- func Invalidate[T any](source Reader[T], window *mygo.Window) (stop func())
- func InvalidateProjection[T, V any](source Reader[T], window *mygo.Window, project func(T) V) func()
- func InvalidateProjectionWith[T, V any](source Reader[T], window *mygo.Window, project func(T) V, ...) func()
- func InvalidateSelector[T any, V any](source Reader[T], window *mygo.Window, selector func(T) V) (stop func())
- func InvalidateSelectorWith[T any, V any](source Reader[T], window *mygo.Window, selector func(T) V, ...) (stop func())
- func SubscribeProjection[T, V any](source Reader[T], project func(T) V, fn func(V)) func()
- func SubscribeProjectionWith[T, V any](source Reader[T], project func(T) V, fn func(current, previous V), ...) func()
- func SubscribeSelector[T any, S any](store Reader[T], selector func(T) S, fn func(S)) func()
- func SubscribeSelectorWith[T any, V any](source Reader[T], selector func(T) V, fn func(current, previous V), ...) func()
- type ActionEvent
- type ActionHooks
- type ActionOptions
- type ActionPolicy
- type ActionTrace
- type AsyncAction
- type AsyncOptions
- type AsyncPersistence
- type AsyncState
- type Codec
- type Definition
- type Derived
- type FileStorage
- type History
- type HistoryOptions
- type JSONCodec
- type JSONMigration
- type LoadError
- type Mutation
- type MutationType
- type PanicError
- type Persistence
- func (p *Persistence[T]) AutoSave(ctx context.Context) func()
- func (p *Persistence[T]) AutoSaveAsync(ctx context.Context, options AsyncOptions) (*AsyncPersistence[T], error)
- func (p *Persistence[T]) AutoSaveWithErrors(ctx context.Context) (<-chan error, func())
- func (p *Persistence[T]) Load(ctx context.Context) error
- func (p *Persistence[T]) LoadBackup(ctx context.Context) error
- func (p *Persistence[T]) Save(ctx context.Context) error
- type PersistenceOptions
- type ReadOnly
- func (r ReadOnly[T]) ActiveTasks() []ActionTrace
- func (r ReadOnly[T]) Done() <-chan struct{}
- func (r ReadOnly[T]) Get() T
- func (r ReadOnly[T]) ID() string
- func (r ReadOnly[T]) Snapshot() Snapshot[T]
- func (r ReadOnly[T]) State() T
- func (r ReadOnly[T]) Subscribe(fn func(Snapshot[T])) func()
- func (r ReadOnly[T]) SubscribeActionTrace(fn func(ActionTrace)) func()
- func (r ReadOnly[T]) SubscribeActions(fn func(ActionEvent)) func()
- func (r ReadOnly[T]) SubscribeMutations(fn func(Mutation[T])) func()
- func (r ReadOnly[T]) SubscribeWith(options SubscribeOptions[T], fn func(Snapshot[T])) func()
- func (r ReadOnly[T]) TaskSnapshot() TaskSnapshot
- func (r ReadOnly[T]) Version() uint64
- func (r ReadOnly[T]) Watch(ctx context.Context, buffer int) <-chan Snapshot[T]
- type Reader
- type Scope
- type SelectorOptions
- type Snapshot
- type Storage
- type Store
- func (s *Store[T]) Action(name string, fn func(*T) error) func() error
- func (s *Store[T]) ActiveTasks() []ActionTrace
- func (s *Store[T]) Batch(fn func()) error
- func (s *Store[T]) Close() error
- func (s *Store[T]) Do(name string, fn func(*T) error) error
- func (s *Store[T]) Done() <-chan struct{}
- func (s *Store[T]) Get() T
- func (s *Store[T]) ID() string
- func (s *Store[T]) Patch(fn func(*T)) error
- func (s *Store[T]) ReadOnly() ReadOnly[T]
- func (s *Store[T]) Reset() error
- func (s *Store[T]) Set(value T) error
- func (s *Store[T]) Snapshot() Snapshot[T]
- func (s *Store[T]) State() T
- func (s *Store[T]) Subscribe(fn func(Snapshot[T])) func()
- func (s *Store[T]) SubscribeActionHooks(hooks ActionHooks) func()
- func (s *Store[T]) SubscribeActionTrace(fn func(ActionTrace)) func()
- func (s *Store[T]) SubscribeActions(fn func(ActionEvent)) func()
- func (s *Store[T]) SubscribeMutations(fn func(Mutation[T])) func()
- func (s *Store[T]) SubscribeWith(options SubscribeOptions[T], fn func(Snapshot[T])) func()
- func (s *Store[T]) TaskSnapshot() TaskSnapshot
- func (s *Store[T]) Transaction(fn func(*T) error) error
- func (s *Store[T]) Update(fn func(*T)) error
- func (s *Store[T]) UpdateErr(fn func(*T) error) error
- func (s *Store[T]) Version() uint64
- func (s *Store[T]) Watch(ctx context.Context, buffer int) <-chan Snapshot[T]
- type SubscribeOptions
- type Task
- type TaskPhase
- type TaskSnapshot
- type VersionedJSONCodec
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrNoUndo = errors.New("nodra: nothing to undo") ErrNoRedo = errors.New("nodra: nothing to redo") )
ErrNoUndo and ErrNoRedo report an empty history stack.
var ( ErrSuperseded = errors.New("nodra: async action superseded") ErrInvalidAction = errors.New("nodra: invalid async action") ErrQueueFull = errors.New("nodra: async action queue full") )
var ( ErrUnsupportedVersion = errors.New("nodra: unsupported schema version") ErrMissingMigration = errors.New("nodra: missing schema migration") )
var ErrClosed = errors.New("nodra: store is closed")
var ErrHistoryBatch = errors.New("nodra: cannot undo or redo inside an open batch")
ErrHistoryBatch reports travel without an independent publication boundary.
var ErrHistoryGroup = errors.New("nodra: cannot undo or redo inside an open history group")
var ErrInvalidPersistence = errors.New("nodra: invalid persistence configuration")
var ErrNoBackup = errors.New("nodra: backup storage unavailable")
Functions ¶
func Invalidate ¶ added in v0.2.0
Invalidate requests a new frame of window's native Content whenever store publishes a snapshot. The subscription stops when the window closes; the returned function stops it earlier and is safe to call repeatedly. Nil inputs and destroyed windows subscribe to nothing. A callback already running when stopped may still request a frame.
func InvalidateProjection ¶ added in v0.6.0
func InvalidateProjection[T, V any](source Reader[T], window *mygo.Window, project func(T) V) func()
InvalidateProjection requests frames only when an owned projection changes, without cloning the entire source. The projector and callbacks follow SubscribeProjection's ownership rules. The window owns the subscription lifetime.
func InvalidateProjectionWith ¶ added in v0.6.0
func InvalidateProjectionWith[T, V any](source Reader[T], window *mygo.Window, project func(T) V, options SelectorOptions[V]) func()
func InvalidateSelector ¶ added in v0.5.0
func InvalidateSelector[T any, V any](source Reader[T], window *mygo.Window, selector func(T) V) (stop func())
InvalidateSelector requests a frame only when the selected value changes, using SubscribeSelector's equality rules. The subscription stops when the window closes or the returned function is called. Selectors run on writer goroutines and must be concurrency-safe; selected reference values follow the store's ownership policy.
func InvalidateSelectorWith ¶ added in v0.5.0
func InvalidateSelectorWith[T any, V any](source Reader[T], window *mygo.Window, selector func(T) V, options SelectorOptions[V]) (stop func())
InvalidateSelectorWith is InvalidateSelector with custom equality and optional immediate invalidation. Nil inputs and destroyed windows subscribe to nothing. As with Invalidate, stopping does not wait for callbacks already running.
func SubscribeProjection ¶ added in v0.6.0
func SubscribeProjectionWith ¶ added in v0.6.0
func SubscribeProjectionWith[T, V any](source Reader[T], project func(T) V, fn func(current, previous V), options SelectorOptions[V]) func()
SubscribeProjectionWith is an opt-in selector that borrows immutable source snapshots instead of cloning the entire Store per notification. project must be pure and concurrency-safe, must not retain or mutate source references, and must return independently owned projections. Callbacks must treat the current/previous projections as immutable. Equality, initialization and callback ordering match SubscribeSelectorWith. On default stores, source reference values must remain immutable as with any retained snapshot.
func SubscribeSelector ¶
func SubscribeSelectorWith ¶
func SubscribeSelectorWith[T any, V any](source Reader[T], selector func(T) V, fn func(current, previous V), options SelectorOptions[V]) func()
SubscribeSelectorWith calls fn with current and previous selected values. It catches up after registration and ignores obsolete computations. Callbacks run on writer goroutines and may overlap, as with Store.Subscribe.
Types ¶
type ActionEvent ¶
type ActionEvent struct {
ID uint64
RunID uint64
Key string
Version uint64
Committed bool
StoreID string
Name string
Started time.Time
Finished time.Time
Duration time.Duration
Err error
}
ActionEvent describes one completed action.
type ActionHooks ¶
type ActionHooks struct {
Before func(ActionEvent)
After func(ActionEvent)
Error func(ActionEvent)
}
ActionHooks observes action lifecycle events. Before runs before the mutation; After runs only on success; Error runs only on failure.
type ActionOptions ¶ added in v0.6.0
type ActionOptions[I any] struct { Policy ActionPolicy Key func(I) string MaxConcurrent int QueueLimit int }
ActionOptions configures cooperative work scheduling. LatestWins (default) replaces only the preceding task with the same Key; nil Key uses one shared key. QueueAll keeps every accepted task. MaxConcurrent bounds work including canceled work that has not returned; zero is unbounded for LatestWins and defaults to one for QueueAll. QueueLimit bounds waiting tasks (default 64 when bounded). Starts are FIFO; with concurrency above one commits follow completion order. Key must be pure and concurrency-safe.
type ActionPolicy ¶ added in v0.6.0
type ActionPolicy uint8
const ( LatestWins ActionPolicy = iota QueueAll )
type ActionTrace ¶ added in v0.6.0
type ActionTrace struct {
ID uint64
RunID uint64
StoreID string
Name string
Key string
Phase TaskPhase
Progress float64
Revision uint64
TaskVersion uint64
Version uint64
Committed bool
At time.Time
Duration time.Duration
Err error
}
ActionTrace observes asynchronous task lifecycles. ID is the source Store action ID; RunID is local to its AsyncAction. Revision orders trace notifications even when callbacks overlap. Version identifies a published commit when Committed is true. Progress is monotonic for one task. Completion ActionEvents remain a separate, backward-compatible stream.
type AsyncAction ¶ added in v0.6.0
type AsyncAction[T, I, R any] struct { // contains filtered or unexported fields }
AsyncAction runs work outside the Store lock with an explicit commit policy. The default accepts only the latest uncanceled run per key. Input and result ownership follows Store's policy; copy mutable inputs before Run. Work must honor its context. Progress, status subscribers and action hooks can run on background goroutines.
func NewAsyncAction ¶ added in v0.6.0
func NewAsyncActionWithOptions ¶ added in v0.6.0
func (*AsyncAction[T, I, R]) Close ¶ added in v0.6.0
func (a *AsyncAction[T, I, R]) Close(ctx context.Context) error
Close prevents new runs, cancels every active run and waits for cooperative work within ctx. The status store closes after the final run's terminal status. A timed-out Close can be called again to wait for remaining work. Do not Close synchronously from work, hooks or subscribers of this action; cancel there and close from the owner instead.
func (*AsyncAction[T, I, R]) Run ¶ added in v0.6.0
func (a *AsyncAction[T, I, R]) Run(ctx context.Context, input I) (*Task, error)
Run accepts work according to ActionOptions. LatestWins supersedes the preceding task with the same key; QueueAll retains every accepted task. Canceled and superseded results never commit. ErrQueueFull rejects work without canceling existing tasks.
func (*AsyncAction[T, I, R]) Status ¶ added in v0.6.0
func (a *AsyncAction[T, I, R]) Status() ReadOnly[AsyncState]
Status returns the observable status of the latest run, suitable for MyGo invalidation or DevTools attachment. Callers must not write to this store.
type AsyncOptions ¶ added in v0.3.0
AsyncOptions configures write-behind persistence. Debounce is a trailing-edge delay for bursts of updates; zero starts immediately. Flush bypasses the delay.
type AsyncPersistence ¶ added in v0.3.0
type AsyncPersistence[T any] struct { // contains filtered or unexported fields }
AsyncPersistence owns one worker and a bounded error stream. It coalesces updates without blocking writer goroutines on encoding or storage. Failed writes remain pending; the next update or Flush retries them without spinning. Values must be immutable or the store must use NewWithClone.
func (*AsyncPersistence[T]) Close ¶ added in v0.3.0
func (a *AsyncPersistence[T]) Close(ctx context.Context) error
Close stops observing updates, flushes the final observed state, then stops the worker even if the flush fails. It is idempotent; concurrent callers wait on the same result with their own context. Do not mutate the store concurrently with Close if those changes must be included. Retry failed shutdown writes with Persistence.Save; a closed async writer cannot be restarted.
func (*AsyncPersistence[T]) Errors ¶ added in v0.3.0
func (a *AsyncPersistence[T]) Errors() <-chan error
Errors reports failed write attempts. The bounded stream may drop errors if unread; Flush and Close return their write error directly. It closes on exit.
func (*AsyncPersistence[T]) Flush ¶ added in v0.3.0
func (a *AsyncPersistence[T]) Flush(ctx context.Context) error
Flush waits until the version visible when called has been saved, bypassing debounce and retrying a previous failure. Canceling this wait does not cancel the shared worker. Later updates may be included in the same write.
type AsyncState ¶ added in v0.6.0
type AsyncState struct {
ID uint64
Name string
Running bool
Progress float64
Error string
Phase TaskPhase
Key string
Revision uint64
}
AsyncState describes the latest run. Progress is between zero and one; Error is diagnostic text. Treat the action's status store as read-only.
type Definition ¶
type Definition[T any] struct { // contains filtered or unexported fields }
Definition is a reusable named store factory, analogous to Pinia's defineStore and Zustand's reusable vanilla store creator.
func Define ¶
func Define[T any](id string, initial func() T) *Definition[T]
Define creates a store definition. Each New call gets independent state.
func DefineWithClone ¶ added in v0.3.0
func DefineWithClone[T any](id string, initial func() T, clone func(T) T) *Definition[T]
DefineWithClone creates a named factory with NewWithClone's isolation policy.
func (*Definition[T]) ID ¶
func (d *Definition[T]) ID() string
func (*Definition[T]) New ¶
func (d *Definition[T]) New() *Store[T]
type Derived ¶
Derived is a memoized getter derived from a store. It recomputes when the source publishes and only notifies listeners when the selected value changes.
func DeriveProjection ¶ added in v0.6.0
func DeriveProjection[T any, V any](source Reader[T], project func(T) V, equals func(V, V) bool) *Derived[T, V]
DeriveProjection memoizes an owned projection without whole-source clones. It follows SubscribeProjection's ownership contract; returned reference values and listener arguments are read-only.
type FileStorage ¶
type FileStorage struct {
Path string
Perm os.FileMode
// Backup writes an independent Path+".bak" copy after each successful primary replacement. A backup failure is returned even though the primary may already contain the new state. Use one Persistence writer per destination.
Backup bool
}
FileStorage stores encoded state at Path. Save writes a temporary file in the same directory and renames it into place, so readers see a complete file.
func (FileStorage) LoadBackup ¶ added in v0.6.0
func (f FileStorage) LoadBackup(ctx context.Context) ([]byte, error)
type History ¶
type History[T any] struct { // contains filtered or unexported fields }
History records successful store snapshots and provides bounded undo/redo.
func Track ¶
Track starts recording changes to store. limit is the maximum number of undo entries; values below one disable history recording.
func TrackWith ¶ added in v0.6.0
func TrackWith[T any](store *Store[T], options HistoryOptions[T]) *History[T]
func (*History[T]) BeginGroup ¶ added in v0.6.0
BeginGroup merges edits across frames into one undo step while still publishing every update. Groups nest; the returned end function is idempotent. Concurrent writers join the group. Undo and Redo are rejected until all groups end. Filtering still applies, so a group containing only ignored changes adds no step.
type HistoryOptions ¶ added in v0.6.0
type HistoryOptions[T any] struct { Limit int Equals func(previous, next T) bool Restore func(current, recorded T) T }
HistoryOptions configures recording. Equals excludes changes to irrelevant fields. Restore merges recorded fields into current state so ignored fields survive travel. Both functions must be pure, must not mutate arguments, and must not reenter the Store or History; they can run while those locks are held. With nil callbacks, every publication records and travel replaces the whole value.
type JSONCodec ¶
type JSONCodec[T any] struct{}
JSONCodec encodes a store value using encoding/json.
type JSONMigration ¶ added in v0.3.0
type JSONMigration func(json.RawMessage) (json.RawMessage, error)
JSONMigration converts one schema version to the next. Inputs and outputs are state JSON, without the version envelope. Return an error to abort Load.
type LoadError ¶ added in v0.6.0
LoadError identifies the failing load stage without changing state or files. Backup distinguishes explicit backup loads. Unwrap preserves codec, validation and filesystem errors.
type Mutation ¶
type Mutation[T any] struct { ActionID uint64 Type MutationType Name string Previous T Value T Version uint64 At time.Time }
Mutation contains Pinia-like subscription metadata.
type MutationType ¶
type MutationType string
MutationType describes why a store published a snapshot.
const ( MutationDirect MutationType = "direct" MutationPatch MutationType = "patch" MutationAction MutationType = "action" MutationReset MutationType = "reset" )
type PanicError ¶ added in v0.6.0
type PanicError struct{ Value any }
PanicError reports a panic at the asynchronous user-code boundary. The Store may already have committed if a notification or completion hook panicked.
func (*PanicError) Error ¶ added in v0.6.0
func (e *PanicError) Error() string
type Persistence ¶
type Persistence[T any] struct { // contains filtered or unexported fields }
Persistence connects a store to a Storage and Codec. It is explicit by default: call Load at startup and Save after successful application actions. Save calls on the same instance are serialized, including state capture and encoding. Separate instances sharing a storage destination are not coordinated.
func NewPersistence ¶
func NewPersistence[T any](store *Store[T], storage Storage, codec Codec[T]) *Persistence[T]
func NewPersistenceWithOptions ¶ added in v0.6.0
func NewPersistenceWithOptions[T any](store *Store[T], storage Storage, codec Codec[T], options PersistenceOptions[T]) *Persistence[T]
func (*Persistence[T]) AutoSave ¶
func (p *Persistence[T]) AutoSave(ctx context.Context) func()
AutoSave subscribes to updates and saves synchronously after each update. The returned function stops autosaving. Use Batch to coalesce writes.
func (*Persistence[T]) AutoSaveAsync ¶ added in v0.3.0
func (p *Persistence[T]) AutoSaveAsync(ctx context.Context, options AsyncOptions) (*AsyncPersistence[T], error)
AutoSaveAsync subscribes and schedules the current state once, then all subsequent versions. Use Close before closing the store to drain writes. Parent cancellation and store closure stop the worker without a guaranteed drain. Storage.Save must respect context cancellation to bound shutdown time.
func (*Persistence[T]) AutoSaveWithErrors ¶
func (p *Persistence[T]) AutoSaveWithErrors(ctx context.Context) (<-chan error, func())
AutoSaveWithErrors subscribes to updates and reports persistence failures on a buffered channel. The channel closes when ctx is canceled or stop is called. Stop releases the background watcher but does not wait for in-flight saves.
func (*Persistence[T]) LoadBackup ¶ added in v0.6.0
func (p *Persistence[T]) LoadBackup(ctx context.Context) error
LoadBackup explicitly restores validated backup state to memory. It never rewrites the primary file, so a corrupt original remains available for diagnosis. Call before starting autosave; a later Save intentionally writes the current state to disk.
type PersistenceOptions ¶ added in v0.6.0
PersistenceOptions validates decoded and saved state before it reaches the Store or storage. Validate must be pure and concurrency-safe, and must not mutate its input.
type ReadOnly ¶ added in v0.6.0
type ReadOnly[T any] struct { // contains filtered or unexported fields }
ReadOnly grants observation without Set, Update, Reset, action hooks or Close. Values still follow the source's cloning/immutability policy; this is a capability boundary, not a deep-freeze operation. Its zero value is an empty, invalid source (Done returns nil).
func (ReadOnly[T]) ActiveTasks ¶ added in v0.6.0
func (r ReadOnly[T]) ActiveTasks() []ActionTrace
func (ReadOnly[T]) SubscribeActionTrace ¶ added in v0.6.0
func (r ReadOnly[T]) SubscribeActionTrace(fn func(ActionTrace)) func()
func (ReadOnly[T]) SubscribeActions ¶ added in v0.6.0
func (r ReadOnly[T]) SubscribeActions(fn func(ActionEvent)) func()
func (ReadOnly[T]) SubscribeMutations ¶ added in v0.6.0
func (ReadOnly[T]) SubscribeWith ¶ added in v0.6.0
func (r ReadOnly[T]) SubscribeWith(options SubscribeOptions[T], fn func(Snapshot[T])) func()
func (ReadOnly[T]) TaskSnapshot ¶ added in v0.6.0
func (r ReadOnly[T]) TaskSnapshot() TaskSnapshot
type Reader ¶ added in v0.6.0
type Reader[T any] interface { Get() T State() T Snapshot() Snapshot[T] Version() uint64 ID() string Done() <-chan struct{} Subscribe(func(Snapshot[T])) func() SubscribeWith(SubscribeOptions[T], func(Snapshot[T])) func() SubscribeMutations(func(Mutation[T])) func() SubscribeActions(func(ActionEvent)) func() SubscribeActionTrace(func(ActionTrace)) func() ActiveTasks() []ActionTrace TaskSnapshot() TaskSnapshot Watch(context.Context, int) <-chan Snapshot[T] // contains filtered or unexported methods }
Reader is the observation surface shared by Store and ReadOnly. Only Nodra sources implement it; a read-only wrapper never exposes its backing Store. Snapshot ownership and callback concurrency are unchanged.
type Scope ¶ added in v0.6.0
type Scope struct {
// contains filtered or unexported fields
}
Scope owns a module's lifetime. Close cancels Context, stops observations, then runs deferred drains in reverse registration order. Register stores first, persistence second, and actions last so work finishes before persistence drains and stores close. Shared stores need not belong to a Scope.
func (*Scope) Close ¶ added in v0.6.0
Close starts shutdown once. Concurrent callers share its result but can stop waiting with their own context. The first caller supplies the drain context; resources receive that deadline even if the caller stops waiting. Persistence that must drain should use an independent worker context, not Scope.Context, which is canceled first.
type SelectorOptions ¶
SelectorOptions configures a selector subscription. With no Equals function, comparable values use == (including pointer identity); other values use reflect.DeepEqual. A custom comparator can use slices.Equal or maps.Equal.
type Snapshot ¶
func Select ¶ added in v0.6.0
Select reads an owned projection and source version without cloning the whole Store. project borrows read-only state under the read lock: it must not mutate or retain source references, reenter the Store, or block. Return scalars or copy all mutable references in the projection (for example with slices.Clone). Existing Get and SubscribeSelector keep their full-state isolation policy.
type Storage ¶
type Storage interface {
Load(context.Context) ([]byte, error)
Save(context.Context, []byte) error
}
Storage is the minimal persistence backend used by Persistence. Files, key-value databases and encrypted stores can implement it.
type Store ¶
type Store[T any] struct { // contains filtered or unexported fields }
func NewWithClone ¶ added in v0.3.0
NewWithClone isolates owned state, snapshots, subscriber values and rollback with clone. Clone must copy all mutable references, be safe for concurrent calls, and must not reenter the store. A nil clone preserves New's behavior.
func (*Store[T]) Action ¶
Action returns a reusable named action function, matching Pinia action definitions while keeping Go's explicit function types.
func (*Store[T]) ActiveTasks ¶ added in v0.6.0
func (s *Store[T]) ActiveTasks() []ActionTrace
ActiveTasks returns queued/running tasks independently of diagnostic sampling. The slice is owned by the caller.
func (*Store[T]) SubscribeActionHooks ¶
func (s *Store[T]) SubscribeActionHooks(hooks ActionHooks) func()
SubscribeActionHooks registers lifecycle hooks and returns an unsubscribe function.
func (*Store[T]) SubscribeActionTrace ¶ added in v0.6.0
func (s *Store[T]) SubscribeActionTrace(fn func(ActionTrace)) func()
func (*Store[T]) SubscribeActions ¶
func (s *Store[T]) SubscribeActions(fn func(ActionEvent)) func()
func (*Store[T]) SubscribeMutations ¶
func (*Store[T]) SubscribeWith ¶
func (s *Store[T]) SubscribeWith(options SubscribeOptions[T], fn func(Snapshot[T])) func()
func (*Store[T]) TaskSnapshot ¶ added in v0.6.0
func (s *Store[T]) TaskSnapshot() TaskSnapshot
func (*Store[T]) Transaction ¶
func (*Store[T]) Update ¶
Example ¶
package main
import (
"fmt"
"github.com/yldm-tech/nodra"
)
func main() {
store := nodra.New(0)
store.Subscribe(func(snapshot nodra.Snapshot[int]) {
fmt.Println(snapshot.Value, snapshot.Version)
})
if err := store.Update(func(value *int) { *value = 42 }); err != nil {
fmt.Println(err)
}
}
Output: 42 1
type SubscribeOptions ¶
type Task ¶ added in v0.6.0
type Task struct {
ID uint64
// contains filtered or unexported fields
}
Task is one run of an AsyncAction. Cancel requests cooperative cancellation; Wait waits for work and its completion notifications, independently of the waiter's context. Do not Wait from the task's own work, hooks or synchronous subscribers.
func (*Task) Status ¶ added in v0.6.0
func (t *Task) Status() ReadOnly[AsyncState]
type TaskSnapshot ¶ added in v0.6.0
type TaskSnapshot struct {
Revision uint64
Tasks []ActionTrace
}
TaskSnapshot identifies current queued/running tasks and the source trace revision at capture time. Terminal tasks are released by the source; Task.Status retains their final state.
type VersionedJSONCodec ¶ added in v0.3.0
type VersionedJSONCodec[T any] struct { Version int Migrations map[int]JSONMigration AllowUnversioned bool }
VersionedJSONCodec stores {"schemaVersion": N, "state": ...}. Migrations[n] upgrades version n to n+1, sequentially. AllowUnversioned accepts legacy raw JSON as version zero. Version must be positive; future versions are rejected. Decode never writes storage: persist a successful upgrade explicitly with Save.
func (VersionedJSONCodec[T]) Decode ¶ added in v0.3.0
func (c VersionedJSONCodec[T]) Decode(data []byte) (T, error)
func (VersionedJSONCodec[T]) Encode ¶ added in v0.3.0
func (c VersionedJSONCodec[T]) Encode(value T) ([]byte, error)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package devtools provides an opt-in local inspector for Nodra stores.
|
Package devtools provides an opt-in local inspector for Nodra stores. |
|
examples
|
|
|
basic
command
|
|
|
devtools
command
Command devtools runs a counter with a live local inspector.
|
Command devtools runs a counter with a live local inspector. |
|
mygo
command
Example mygo demonstrates two native windows sharing business state with independent redraw subscriptions.
|
Example mygo demonstrates two native windows sharing business state with independent redraw subscriptions. |
|
persistent
command
Command persistent demonstrates cloned state, schema migration and write-behind persistence.
|
Command persistent demonstrates cloned state, schema migration and write-behind persistence. |
|
workbench
command
Command workbench searches real local file names and edits persisted settings.
|
Command workbench searches real local file names and edits persisted settings. |
