Documentation
¶
Overview ¶
Package vango provides the reactive core for the Vango framework.
The reactive system provides fine-grained reactivity similar to SolidJS, where dependencies are tracked automatically at runtime. Reading a signal during component render automatically subscribes the component to that signal's changes.
Core Types ¶
Signal[T] is a reactive value container:
count := setup.Signal(&s, 0)
value := count.Get() // Read (subscribes current listener)
count.Set(5) // Write (notifies subscribers)
count.Update(func(n int) int { return n + 1 })
Memo[T] is a cached derived computation:
doubled := newMemo(func() int { return count.Get() * 2 })
value := doubled.Get() // Recomputes only if dependencies changed
Effect runs side effects when dependencies change:
Effect(func() Cleanup {
fmt.Println("Count is:", count.Get())
return func() { /* cleanup */ }
})
Batching ¶
Multiple signal updates can be batched to trigger a single notification:
Batch(func() {
a.Set(1)
b.Set(2)
c.Set(3)
}) // Single notification after all updates
Thread Safety ¶
All reactive primitives are thread-safe and can be accessed from multiple goroutines. The tracking context is per-goroutine, so spawning goroutines requires explicit context propagation via WithOwner.
Index ¶
- Constants
- Variables
- func AsCircularDependencyPanic(v any) (cycle []MemoRef, current MemoRef, reentryIdx int, ok bool)
- func AssertNoPanic(t *testing.T, fn func())
- func AssertPanics(t *testing.T, fn func()) (panicValue any)
- func Batch(fn func())
- func ClearSessionKeyRegistry()
- func DecodeHookPayload[T any](event HookEvent) (T, error)
- func DecodeIslandPayload[T any](msg IslandMessage) (T, error)
- func DecodeWasmPayload[T any](msg WasmMessage) (T, error)
- func DisallowedLogKeyFragments() []string
- func FormatMemoCycle(cycle []MemoRef) string
- func Func(render func() *vdom.VNode) vdom.Component
- func GetContext(key any) any
- func GetEffectCallSiteState[T any](factory func() *T) *T
- func GetSessionKeyRegistry() map[string]SessionKeyInfo
- func GetSessionRefreshBanner() func(Ctx) BannerSpec
- func InRender() bool
- func InSessionLoop() bool
- func InSetup() bool
- func InitPersistBannerState(owner *Owner)
- func IsDevMode() bool
- func IsPrefetchMode() bool
- func IsStrictConcurrency() bool
- func OnSessionRefreshBanner(fn func(Ctx) BannerSpec)
- func OnUnmount(fn func())
- func RedactPII(fields ...any) []any
- func SetContext(key, value any)
- func SetDevMode(enabled bool)
- func SetGlobalMetricsSink(sink MetricsSink)
- func SetHookSlot(value any)
- func SetStrictConcurrency(enabled bool)
- func Setup[P any](props P, fn func(SetupCtx[P]) RenderFn) vdom.Component
- func SetupOnChange[P any, K comparable](s *SetupCtx[P], key func() K, cb func(next, prev K))
- func ShowDefaultPersistBanner(err *PersistBudgetError)
- func TestBatch(t *testing.T, fn func())
- func TestDevMode(t *testing.T, fn func())
- func TestID(id string) vdom.Attr
- func TestProdMode(t *testing.T, fn func())
- func TestSessionLoop(t *testing.T, fn func())
- func TestSetup(t *testing.T, fn func())
- func TestWithOwner(t *testing.T, owner *Owner, fn func())
- func TrackHook(ht HookType)
- func Tx(fn func())
- func TxNamed(name string, fn func())
- func Untracked(fn func())
- func UntrackedGet[T any](s *Signal[T]) T
- func UseHookSlot() any
- func WithCtx(c any, fn func())
- func WithListener(l Listener, fn func())
- func WithOwner(owner *Owner, fn func())
- func WithRenderAllocationsDisabled(fn func())
- func WithSessionLoop(fn func())
- func WithSetup(fn func())
- func WithTxTraceHook(ctx context.Context, hook TxTraceHook) context.Context
- func WithWorkerContext(kind WorkerKind, meta *primitiveMetadata, runtimeCtx Ctx, fn func())
- type Action
- func (a *Action[A, R]) Error() error
- func (a *Action[A, R]) IsError() bool
- func (a *Action[A, R]) IsIdle() bool
- func (a *Action[A, R]) IsRunning() bool
- func (a *Action[A, R]) IsSuccess() bool
- func (a *Action[A, R]) Match(handlers ...ActionHandler[A, R]) *vdom.VNode
- func (a *Action[A, R]) Metadata() vruntime.PrimitiveMetadata
- func (a *Action[A, R]) Reset()
- func (a *Action[A, R]) Result() (R, bool)
- func (a *Action[A, R]) Run(arg A) bool
- func (a *Action[A, R]) State() ActionState
- type ActionHandler
- func OnActionError[A any, R any](fn func(error) *vdom.VNode) ActionHandler[A, R]
- func OnActionIdle[A any, R any](fn func() *vdom.VNode) ActionHandler[A, R]
- func OnActionRunning[A any, R any](fn func() *vdom.VNode) ActionHandler[A, R]
- func OnActionSuccess[A any, R any](fn func(R) *vdom.VNode) ActionHandler[A, R]
- type ActionOption
- func ActionOnError(fn func(error)) ActionOption
- func ActionOnSuccess(fn func(any)) ActionOption
- func ActionTxName(name string) ActionOption
- func CancelLatest() ActionOption
- func DropWhileRunning() ActionOption
- func OnActionRejected(fn func(ActionRejection)) ActionOption
- func OnActionStart(fn func()) ActionOption
- func Queue(maxQueue int) ActionOption
- type ActionPanicError
- type ActionRejection
- type ActionRejectionReason
- type ActionState
- type AnimationEvent
- type BannerSpec
- type BoolSignaldeprecated
- type BudgetExceededMode
- type BudgetKind
- type BudgetScope
- type BudgetStats
- type BudgetTracker
- func (bt *BudgetTracker) CheckAndRecord(scope BudgetScope, sessionID, stableID, debugName string, newBytes int64) *PersistBudgetError
- func (bt *BudgetTracker) EncodedSize(value any) (int64, error)
- func (bt *BudgetTracker) GetSessionSize(sessionID string) int64
- func (bt *BudgetTracker) RecordExisting(sessionID, stableID string, bytes int64)
- func (bt *BudgetTracker) RemoveSession(sessionID string)
- func (bt *BudgetTracker) SetMetricsCallbacks(onWrite func(scope BudgetScope, stableID string, bytes int64), ...)
- type Cleanup
- func GoLatest[K comparable, R any](key K, work func(ctx context.Context, key K) (R, error), ...) Cleanup
- func Interval(d time.Duration, fn func(), opts ...IntervalOption) Cleanup
- func Subscribe[T any](stream Stream[T], fn func(T), opts ...SubscribeOption) Cleanup
- func Timeout(d time.Duration, fn func(), opts ...TimeoutOption) Cleanup
- type Component
- type ConcurrencyPolicy
- type Context
- type Ctx
- type DebugConfig
- type Dependency
- type DependencyTracker
- type DragEvent
- type DropEvent
- type Effect
- type EffectOption
- type EventRateLimitConfig
- type Float64Signaldeprecated
- type FormData
- type GlobalBroadcastBackend
- type GlobalPersistenceBackend
- type GlobalSignalStore
- func (gs *GlobalSignalStore) ApplyEncoded(stableID string, encoded []byte) (bool, error)
- func (gs *GlobalSignalStore) GetOrCreateSignal(ctx context.Context, stableID string, fingerprint codec.Fingerprint, ...) (any, error)
- func (gs *GlobalSignalStore) RefreshAll(ctx context.Context) ([]GlobalSignalUpdate, error)
- func (gs *GlobalSignalStore) Set(stableID string, value any) error
- func (gs *GlobalSignalStore) SetBroadcastHandler(ctx context.Context, handler func(stableID string, encoded []byte))
- func (gs *GlobalSignalStore) SetBudgetTracker(tracker *BudgetTracker)
- type GlobalSignalStoreOption
- type GlobalSignalUpdate
- type GoLatestOption
- type HTTPError
- func BadRequest(err error) *HTTPError
- func BadRequestf(format string, args ...any) *HTTPError
- func Conflict(message ...string) *HTTPError
- func Forbidden(message ...string) *HTTPError
- func InternalError(err error) *HTTPError
- func NotFound(message ...string) *HTTPError
- func ServiceUnavailable(message ...string) *HTTPError
- func Unauthorized(message ...string) *HTTPError
- func UnprocessableEntity(message ...string) *HTTPError
- type Handler
- type HookEvent
- func (h HookEvent) Bool(key string) bool
- func (h HookEvent) Float(key string) float64
- func (h HookEvent) Get(key string) any
- func (h HookEvent) GetBool(key string) bool
- func (h HookEvent) GetFloat(key string) float64
- func (h HookEvent) GetInt(key string) int
- func (h HookEvent) GetString(key string) string
- func (h HookEvent) GetStrings(key string) []string
- func (h HookEvent) Int(key string) int
- func (h HookEvent) Raw(key string) any
- func (h HookEvent) Revert()
- func (h *HookEvent) SetContext(hid string, dispatch func(name string, payload any))
- func (h HookEvent) String(key string) string
- func (h HookEvent) Strings(key string) []string
- type HookEventValidator
- type HookType
- type InputEvent
- type Int64Signaldeprecated
- type IntSignaldeprecated
- type IntervalOption
- type IslandMessage
- type IslandMessageHandler
- type IslandMessageValidator
- type IslandMessenger
- type KeyMod
- type KeyboardEvent
- type Listener
- type MapSignaldeprecated
- func (s *MapSignal[K, V]) Clear()
- func (s *MapSignal[K, V]) DeleteKey(key K)
- func (s *MapSignal[K, V]) GetKey(key K) (V, bool)
- func (s *MapSignal[K, V]) HasKey(key K) bool
- func (s *MapSignal[K, V]) Keys() []K
- func (s *MapSignal[K, V]) Len() int
- func (s *MapSignal[K, V]) RemoveKey(key K)
- func (s *MapSignal[K, V]) SetKey(key K, value V)
- func (s *MapSignal[K, V]) UpdateKey(key K, fn func(V) V)
- func (s *MapSignal[K, V]) Values() []V
- type Memo
- type MemoRef
- type MetricsSink
- type ModifiedHandler
- func Capture(handler any) ModifiedHandler
- func Debounce(duration time.Duration, handler any) ModifiedHandler
- func Hotkey(key string, handler any) ModifiedHandler
- func KeyWithModifiers(key string, mods KeyMod, handler any) ModifiedHandler
- func Keys(keys []string, handler any) ModifiedHandler
- func Once(handler any) ModifiedHandler
- func Passive(handler any) ModifiedHandler
- func PreventDefault(handler any) ModifiedHandler
- func Self(handler any) ModifiedHandler
- func StopPropagation(handler any) ModifiedHandler
- func Throttle(duration time.Duration, handler any) ModifiedHandler
- type MouseEvent
- type NavigateEvent
- type NoProps
- type NoopMetricsSink
- func (NoopMetricsSink) RecordActionDuration(string, int64)
- func (NoopMetricsSink) RecordActionError(string)
- func (NoopMetricsSink) RecordColdDeployAck(string)
- func (NoopMetricsSink) RecordPatchBytes(string, int)
- func (NoopMetricsSink) RecordPatchMismatch(string)
- func (NoopMetricsSink) RecordPersistBytes(string, int64)
- func (NoopMetricsSink) RecordPersistWriteRejected(string, string)
- func (NoopMetricsSink) RecordResourceDuration(string, int64)
- func (NoopMetricsSink) RecordResourceError(string)
- func (NoopMetricsSink) RecordResumeFailure(string)
- func (NoopMetricsSink) RecordResumeSuccess()
- func (NoopMetricsSink) RecordSchemaMismatch(string)
- func (NoopMetricsSink) RecordSessionActive(int)
- func (NoopMetricsSink) RecordSessionDetached(int)
- func (NoopMetricsSink) RecordSessionPersistBytes(string, int64)
- func (NoopMetricsSink) RecordSignalWriteViolation(string, string)
- type ObservabilityConfig
- type OnChangeRegistration
- type OnMountRegistration
- type Owner
- func (o *Owner) Dispose()
- func (o *Owner) EndRender()
- func (o *Owner) GetValue(key any) any
- func (o *Owner) GetValueLocal(key any) any
- func (o *Owner) HasPendingEffects() bool
- func (o *Owner) ID() uint64
- func (o *Owner) IsDisposed() bool
- func (o *Owner) MemoryUsage() int64
- func (o *Owner) OnCleanup(fn func())
- func (o *Owner) Parent() *Owner
- func (o *Owner) RunPendingEffects(budget StormBudgetChecker)
- func (o *Owner) SetHookSlot(value any)
- func (o *Owner) SetValue(key, value any)
- func (o *Owner) StartRender()
- func (o *Owner) TrackHook(ht HookType)
- func (o *Owner) UseHookSlot() any
- type PagedResponse
- type PersistBannerState
- type PersistBudgetError
- type PersistedSignalStore
- func (ps *PersistedSignalStore) ClearDirty()
- func (ps *PersistedSignalStore) DirtySignals() []string
- func (ps *PersistedSignalStore) GetOrCreateSignal(stableID string, fingerprint codec.Fingerprint, initializer func() any, ...) (any, error)
- func (ps *PersistedSignalStore) HasDirty() bool
- func (ps *PersistedSignalStore) Restore(data map[string][]byte)
- func (ps *PersistedSignalStore) Serialize() (map[string][]byte, error)
- func (ps *PersistedSignalStore) Set(stableID string, value any) error
- type PrefetchModeChecker
- type PrimitiveRegistration
- type Props
- type PropsCell
- type RenderFn
- type ResizeEvent
- type Resource
- func (r *Resource[T]) Data() T
- func (r *Resource[T]) DataOr(fallback T) T
- func (r *Resource[T]) Error() error
- func (r *Resource[T]) Fetch()
- func (r *Resource[T]) Invalidate()
- func (r *Resource[T]) IsError() bool
- func (r *Resource[T]) IsLoading() bool
- func (r *Resource[T]) IsReady() bool
- func (r *Resource[T]) Match(handlers ...Handler[T]) *vdom.VNode
- func (r *Resource[T]) Metadata() vruntime.PrimitiveMetadata
- func (r *Resource[T]) Mutate(fn func(T) T)
- func (r *Resource[T]) OnError(fn func(error)) *Resource[T]
- func (r *Resource[T]) OnSuccess(fn func(T)) *Resource[T]
- func (r *Resource[T]) Refetch()
- func (r *Resource[T]) ResourceCacheSize(n int) *Resource[T]
- func (r *Resource[T]) RetryOnError(count int, delay time.Duration) *Resource[T]
- func (r *Resource[T]) StaleTime(d time.Duration) *Resource[T]
- func (r *Resource[T]) State() State
- type ResourceOption
- type Response
- type ScrollEvent
- type Session
- type SessionKey
- func (sk *SessionKey[T]) CodecFingerprint() codec.Fingerprint
- func (sk *SessionKey[T]) DefaultValue() T
- func (sk *SessionKey[T]) Delete(ctx Ctx)
- func (sk *SessionKey[T]) Get(ctx Ctx) T
- func (sk *SessionKey[T]) HasDefault() bool
- func (sk *SessionKey[T]) Name() string
- func (sk *SessionKey[T]) Peek(ctx Ctx) (T, bool)
- func (sk *SessionKey[T]) Set(ctx Ctx, value T) error
- func (sk *SessionKey[T]) StableID() string
- type SessionKeyInfo
- type SessionKeyOption
- type SessionSignalStore
- type SetupComponent
- type SetupComponentDetector
- type SetupComponentInvoker
- type SetupCtx
- func (s SetupCtx[P]) Ctx() Ctx
- func (s SetupCtx[P]) Effect(fn func() Cleanup)
- func (s SetupCtx[P]) OnChange(key func() any, cb func(next, prev any))
- func (s SetupCtx[P]) OnMount(fn func() Cleanup)
- func (s SetupCtx[P]) OnPersistError(fn func(*PersistBudgetError))
- func (s SetupCtx[P]) Props() PropsCell[P]
- type SetupState
- func (s *SetupState) AddOnMount(reg *OnMountRegistration)
- func (s *SetupState) AddRegistration(reg PrimitiveRegistration)
- func (s *SetupState) Dispose()
- func (s *SetupState) GetRenderFn() RenderFn
- func (s *SetupState) IsOnMountPending() bool
- func (s *SetupState) IsSetupComplete() bool
- func (s *SetupState) MarkSetupComplete()
- func (s *SetupState) Registrations() []PrimitiveRegistration
- func (s *SetupState) RunOnMountHooks()
- func (s *SetupState) SetOnMountPending(pending bool)
- func (s *SetupState) SetRenderFn(fn RenderFn)
- func (s *SetupState) UpdateProps(newProps any) bool
- type Signal
- func (s *Signal[T]) Add(n any)
- func (s *Signal[T]) Append(suffix string)
- func (s *Signal[T]) AppendItem(item any)
- func (s *Signal[T]) Clear()
- func (s *Signal[T]) Dec()
- func (s *Signal[T]) Div(n any)
- func (s *Signal[T]) Filter(predicate func(any) bool)
- func (s *Signal[T]) Get() T
- func (s *Signal[T]) GetAny() any
- func (s *Signal[T]) HasKey(key any) bool
- func (s *Signal[T]) ID() uint64
- func (s *Signal[T]) Inc()
- func (s *Signal[T]) InsertAt(index int, item any)
- func (s *Signal[T]) Len() int
- func (s *Signal[T]) Metadata() vruntime.PrimitiveMetadata
- func (s *Signal[T]) Mul(n any)
- func (s *Signal[T]) Peek() T
- func (s *Signal[T]) Prepend(prefix string)
- func (s *Signal[T]) PrependItem(item any)
- func (s *Signal[T]) RemoveAt(index int)
- func (s *Signal[T]) RemoveFirst()
- func (s *Signal[T]) RemoveKey(key any)
- func (s *Signal[T]) RemoveLast()
- func (s *Signal[T]) RemoveWhere(predicate func(any) bool)
- func (s *Signal[T]) Set(value T)
- func (s *Signal[T]) SetAny(value any) error
- func (s *Signal[T]) SetAt(index int, item any)
- func (s *Signal[T]) SetFalse()
- func (s *Signal[T]) SetKey(key, value any)
- func (s *Signal[T]) SetTrue()
- func (s *Signal[T]) Sub(n any)
- func (s *Signal[T]) Toggle()
- func (s *Signal[T]) Unsubscribe(listener Listener)
- func (s *Signal[T]) Update(fn func(T) T)
- func (s *Signal[T]) UpdateAt(index int, fn func(any) any)
- func (s *Signal[T]) UpdateKey(key any, fn func(any) any)
- func (s *Signal[T]) UpdateWhere(predicate func(any) bool, fn func(any) any)
- func (s *Signal[T]) WithEquals(fn func(T, T) bool) *Signal[T]
- type SimpleSessionSignalStore
- type SliceSignaldeprecated
- func (s *SliceSignal[T]) Append(item T)
- func (s *SliceSignal[T]) AppendAll(items ...T)
- func (s *SliceSignal[T]) Clear()
- func (s *SliceSignal[T]) Filter(predicate func(T) bool)
- func (s *SliceSignal[T]) InsertAt(index int, item T)
- func (s *SliceSignal[T]) Len() int
- func (s *SliceSignal[T]) Prepend(item T)
- func (s *SliceSignal[T]) RemoveAt(index int)
- func (s *SliceSignal[T]) RemoveFirst()
- func (s *SliceSignal[T]) RemoveLast()
- func (s *SliceSignal[T]) RemoveWhere(predicate func(T) bool)
- func (s *SliceSignal[T]) SetAt(index int, item T)
- func (s *SliceSignal[T]) UpdateAt(index int, fn func(T) T)
- func (s *SliceSignal[T]) UpdateWhere(predicate func(T) bool, fn func(T) T)
- type Slot
- type State
- type StateBudgetConfig
- type StormBudgetChecker
- type StormBudgetConfig
- type StormBudgetTracker
- func (t *StormBudgetTracker) CheckAction() error
- func (t *StormBudgetTracker) CheckEffectRun() error
- func (t *StormBudgetTracker) CheckGoLatest() error
- func (t *StormBudgetTracker) CheckResource() error
- func (t *StormBudgetTracker) GetOnExceeded() BudgetExceededMode
- func (t *StormBudgetTracker) ResetTick()
- func (t *StormBudgetTracker) Stats() BudgetStats
- type Stream
- type StrictEffectMode
- type StringSignaldeprecated
- type SubscribeOption
- type TimeoutOption
- type Touch
- type TouchEvent
- type TrackingContext
- type TransitionEvent
- type TxTraceEvent
- type TxTraceHook
- type TypeMismatchError
- type TypedPropsCell
- type VKind
- type VNode
- type WasmMessage
- type WasmMessageHandler
- type WasmMessageValidator
- type WasmMessenger
- type WheelEvent
- type WorkerContext
- type WorkerKind
Constants ¶
const ( DefaultPerPrimitiveBytes int64 = 64 * 1024 // 64KB DefaultPerSessionBytes int64 = 512 * 1024 // 512KB )
Default budget limits for persisted state.
const ( KindElement = vdom.KindElement KindText = vdom.KindText KindFragment = vdom.KindFragment KindComponent = vdom.KindComponent KindRaw = vdom.KindRaw )
Re-export VKind constants
const ( // Control keys KeyEnter = "Enter" KeyEscape = "Escape" KeySpace = " " KeyTab = "Tab" KeyBackspace = "Backspace" KeyDelete = "Delete" // Arrow keys KeyArrowUp = "ArrowUp" KeyArrowDown = "ArrowDown" KeyArrowLeft = "ArrowLeft" KeyArrowRight = "ArrowRight" // Navigation keys KeyHome = "Home" KeyEnd = "End" KeyPageUp = "PageUp" KeyPageDown = "PageDown" // Function keys KeyF1 = "F1" KeyF2 = "F2" KeyF3 = "F3" KeyF4 = "F4" KeyF5 = "F5" KeyF6 = "F6" KeyF7 = "F7" KeyF8 = "F8" KeyF9 = "F9" KeyF10 = "F10" KeyF11 = "F11" KeyF12 = "F12" // Modifier keys (for reference, usually checked via event flags) KeyControl = "Control" KeyShift = "Shift" KeyAlt = "Alt" KeyMeta = "Meta" // Other common keys KeyInsert = "Insert" KeyPrintScreen = "PrintScreen" KeyScrollLock = "ScrollLock" KeyPause = "Pause" KeyCapsLock = "CapsLock" KeyNumLock = "NumLock" KeyContextMenu = "ContextMenu" )
Common key constants matching JavaScript KeyboardEvent.key values.
const DefaultPersistBannerCSS = `` /* 527-byte string literal not displayed */
DefaultPersistBannerCSS provides CSS for the default banner.
const GlobalSignalPrefix = "vango:global:{global}:"
GlobalSignalPrefix is the persistence key prefix for global signals.
The constant hash tag "{global}" ensures Redis Cluster co-location for all global signal keys so multi-key atomic operations (MULTI/EXEC) can be used safely for Tx-level all-or-nothing durability.
const LintIgnoreDirective = "vango:lint-ignore"
LintIgnoreDirective documents the lint ignore directive for Vango tooling. Usage: //vango:lint-ignore VANGO.SETUP.CONDITIONAL_ALLOC
const SessionKeyInternalPrefix = "vango:sessionkey:"
SessionKeyInternalPrefix is the in-memory prefix for typed session keys.
Variables ¶
var Debug = DefaultDebugConfig()
Debug is the global debug configuration. Modify this at application startup to enable debugging features.
var DebugMode bool
DebugMode enables debug logging throughout the vango package. When true, operations like TxNamed will log transaction boundaries. This should be set at startup and not changed during runtime.
var DevMode = false
DevMode enables development-time checks and panics for invalid operations. When true:
- Signal writes outside session loop panic with descriptive messages
- Signal writes in prefetch mode panic
- Signal writes during render/setup panic
- Effect/Interval/Timeout in prefetch mode panic
- More verbose logging and error messages
When false (production):
- Invalid writes are dropped and logged (no crash)
- Minimal overhead
DevMode is automatically enabled when running tests (*.test binaries). For production, set explicitly at application startup:
func main() {
vango.DevMode = os.Getenv("VANGO_DEV") == "1"
// ...
}
var EffectStrictMode = StrictEffectOff
EffectStrictMode controls global effect-time write detection. Set this in your application initialization based on build mode.
Example:
func init() {
if os.Getenv("VANGO_DEV") == "1" {
vango.EffectStrictMode = vango.StrictEffectWarn
}
}
var ErrActionPanicked = errors.New("vango: action work panicked")
ErrActionPanicked is returned when Action work panics.
The Action runtime recovers panics from user work functions and surfaces them as ActionError state so one faulty action invocation cannot crash the process.
var ErrActionRunning = errors.New("vango: action already running")
ErrActionRunning is returned when attempting to run an Action that is already in the Running state and the concurrency policy is DropWhileRunning.
Applications can safely ignore this error as it's expected behavior for de-duplicating rapid user actions.
var ErrBudgetExceeded = errors.New("vango: storm budget exceeded")
ErrBudgetExceeded is returned when a storm budget limit is exceeded. This happens when too many operations (Resource fetches, Action runs, etc.) occur within the configured time window.
Applications should handle this by: - Logging the event for debugging - Optionally showing user feedback about rate limiting - Reducing the frequency of operations if possible
See SPEC_ADDENDUM.md §A.4 for storm budget configuration.
var ErrEffectContext = errors.New("vango: effect helper called outside effect/render context")
ErrEffectContext is returned when an effect helper (Interval, Subscribe, GoLatest) is called outside of an effect body or render context.
These helpers require access to the runtime context (Ctx) and must be called within createEffect or during component render.
var ErrGoLatestContext = errors.New("vango: GoLatest must be called inside an Effect")
ErrGoLatestContext is returned when GoLatest is called outside an effect body. GoLatest requires effect-local storage and must be called from within createEffect.
var ErrNoSession = errors.New("vango: no active session")
ErrNoSession is returned when a session-backed operation is invoked without an active session.
var ErrQueueFull = errors.New("vango: action queue full")
ErrQueueFull is an admission-control sentinel used when an Action's queue is full and cannot accept more work items (ConcurrencyQueue policy).
IMPORTANT: The runtime does not set ErrQueueFull as Action.Error(); a full queue is not a work failure. Instead, Action.Run returns false and, if configured, OnActionRejected is invoked.
Applications should handle this by: - Informing the user their action was not queued - Waiting before retrying - Using a different concurrency policy if appropriate
See SPEC_ADDENDUM.md §A.1.5 for concurrency policies.
var ErrSessionKeyUnbound = errors.New("vango: session key missing bindings; run 'vango gen bindings'")
ErrSessionKeyUnbound is returned when a SessionKey has no binding.
var ErrTransactionAborted = errors.New("vango: transaction aborted")
ErrTransactionAborted is returned when a write occurs after a transaction abort.
var ErrUnknownPersistedSignal = errors.New("vango: persisted signal not found")
ErrUnknownPersistedSignal indicates a missing persisted signal entry.
var ErrWriteForbidden = errors.New("vango: write must occur on the session loop")
ErrWriteForbidden is returned when a write is attempted outside the session loop.
var GlobalSignalStoreKey = &struct{ name string }{"GlobalSignalStore"}
GlobalSignalStoreKey is the context key for global persisted signals.
var LoggerKey = &struct{ name string }{"Logger"}
LoggerKey stores the structured logger in the owner context.
var MetricsKey = &struct{ name string }{"Metrics"}
MetricsKey stores a metrics sink in the owner context.
var ObservabilityConfigKey = &struct{ name string }{"ObservabilityConfig"}
ObservabilityConfigKey stores observability settings in the owner context.
var PersistBannerDisabledKey = &struct{ name string }{"PersistBannerDisabled"}
PersistBannerDisabledKey stores a bool indicating default banner suppression.
var PersistBannerSignalKey = &struct{ name string }{"PersistBannerSignal"}
PersistBannerSignalKey stores the banner visibility signal in context.
var PersistedSignalStoreKey = &struct{ name string }{"PersistedSignalStore"}
PersistedSignalStoreKey is the context key for session-scoped persisted signals.
var SessionPersistBannerKey = &struct{ name string }{"SessionPersistBanner"}
SessionPersistBannerKey stores PersistBannerState in session context.
var SessionSignalStoreKey = &struct{ name string }{"SessionSignalStore"}
SessionSignalStoreKey is the context key for the session signal store. The server package should set this during session initialization.
var StrictConcurrency = false
StrictConcurrency forces session-loop-only write enforcement to panic even when DevMode is false.
Default: false (production-safe: drop + warn + metric).
This is useful for staging/canary environments where you want concurrency violations to crash loudly before reaching production.
Functions ¶
func AsCircularDependencyPanic ¶
AsCircularDependencyPanic extracts structured cycle information from a panic value. This is intended for session containment and tests.
func AssertNoPanic ¶
AssertNoPanic asserts that fn does not panic. If fn panics, the test fails with the panic message.
Example:
func TestValidOperation(t *testing.T) {
AssertNoPanic(t, func() {
// Code that should not panic
})
}
func AssertPanics ¶
AssertPanics asserts that fn panics. If fn does not panic, the test fails. If fn panics, the panic value is returned for further inspection.
Example:
func TestInvalidOperation(t *testing.T) {
msg := AssertPanics(t, func() {
// Code that should panic
})
if !strings.Contains(fmt.Sprint(msg), "forbidden") {
t.Fatalf("unexpected panic message: %v", msg)
}
}
func Batch ¶
func Batch(fn func())
Batch groups multiple signal updates into a single notification phase. All signal updates within the batch function are collected, deduplicated, and then all affected listeners are notified once when the batch completes.
This is useful for updating multiple related signals without triggering intermediate re-renders.
Batches can be nested. Notifications only fire when the outermost batch completes.
Example:
Batch(func() {
firstName.Set("John")
lastName.Set("Doe")
age.Set(30)
})
// Component re-renders once with all three changes
func ClearSessionKeyRegistry ¶
func ClearSessionKeyRegistry()
ClearSessionKeyRegistry clears the registry (for tests).
func DecodeHookPayload ¶
DecodeHookPayload decodes hook payload data into a typed schema. Unknown fields and trailing JSON content are rejected.
func DecodeIslandPayload ¶
func DecodeIslandPayload[T any](msg IslandMessage) (T, error)
DecodeIslandPayload decodes an island message payload into a typed schema. Unknown fields and trailing JSON content are rejected.
func DecodeWasmPayload ¶
func DecodeWasmPayload[T any](msg WasmMessage) (T, error)
DecodeWasmPayload decodes a WASM message payload into a typed schema. Unknown fields and trailing JSON content are rejected.
func DisallowedLogKeyFragments ¶
func DisallowedLogKeyFragments() []string
DisallowedLogKeyFragments returns fragments that are redacted by RedactPII.
func FormatMemoCycle ¶
FormatMemoCycle formats a cycle chain as a deterministic string suitable for logs.
func Func ¶
Func wraps a render function as a Component. Deprecated: Use vango.Setup for all stateful components.
Example:
func Counter(initial int) vango.Component {
return vango.Setup(vango.NoProps{}, func(s vango.SetupCtx[vango.NoProps]) vango.RenderFn {
count := setup.Signal(&s, initial)
return func() *vango.VNode {
return Div(
H1(Textf("Count: %d", count.Get())),
Button(OnClick(count.Inc), Text("+")),
)
}
})
}
func GetContext ¶
GetContext retrieves a context value from the nearest provider in the hierarchy. Returns nil if no value is found.
func GetEffectCallSiteState ¶
func GetEffectCallSiteState[T any](factory func() *T) *T
GetEffectCallSiteState retrieves or creates typed state for the current call-site within the currently executing Effect. This is the primary API for effect helpers like GoLatest that need to maintain state across effect reruns.
The factory function is called only on first invocation for this call-site. Subsequent calls (in effect reruns) return the previously created state.
Returns nil if called outside an effect body.
Usage pattern in effect helpers:
func GoLatest[K, R any](...) Cleanup {
state := GetEffectCallSiteState(func() *goLatestState[K] {
return &goLatestState[K]{}
})
if state == nil {
panic("GoLatest must be called inside an Effect")
}
// Use state...
}
func GetSessionKeyRegistry ¶
func GetSessionKeyRegistry() map[string]SessionKeyInfo
GetSessionKeyRegistry returns all registered session keys by name.
func GetSessionRefreshBanner ¶
func GetSessionRefreshBanner() func(Ctx) BannerSpec
GetSessionRefreshBanner returns the current banner handler, if any.
func InRender ¶
func InRender() bool
InRender reports whether the current goroutine is inside a render phase. This is intended for framework-internal use.
func InSessionLoop ¶
func InSessionLoop() bool
InSessionLoop reports whether the current goroutine is executing on the session loop (single-writer context). This is primarily used by the server runtime to enforce correctness contracts around Dispatch and state writes.
func InSetup ¶
func InSetup() bool
InSetup reports whether the current goroutine is inside a Setup execution. This is primarily intended for framework packages that enforce setup-time contracts on helper APIs.
func InitPersistBannerState ¶
func InitPersistBannerState(owner *Owner)
InitPersistBannerState initializes banner state for a session owner. Intended for server/session setup; not for application code.
func IsPrefetchMode ¶
func IsPrefetchMode() bool
IsPrefetchMode returns true if the current context is in prefetch mode. This is used by Signal.Set(), Effect(), Interval(), Timeout(), and Action() to enforce read-only behavior during prefetch.
Per Section 8.3.2 of the Routing Spec:
- Dev mode: Operations panic with descriptive message
- Prod mode: Operations are silently dropped (no-op)
func IsStrictConcurrency ¶
func IsStrictConcurrency() bool
IsStrictConcurrency reports whether strict concurrency mode is enabled.
func OnSessionRefreshBanner ¶
func OnSessionRefreshBanner(fn func(Ctx) BannerSpec)
OnSessionRefreshBanner registers a handler to customize schema refresh banners.
func OnUnmount ¶
func OnUnmount(fn func())
OnUnmount registers a function to run when the owner is disposed. This is typically used for cleanup when a component unmounts.
Example:
OnUnmount(func() {
fmt.Println("Component unmounted")
})
func RedactPII ¶
RedactPII replaces values for disallowed keys in key/value pairs or slog.Attr entries. It does not attempt to scrub content inside strings; it only checks keys.
func SetContext ¶
func SetContext(key, value any)
SetContext sets a context value for the current component scope. This value will be available to all descendants via GetContext.
func SetDevMode ¶
func SetDevMode(enabled bool)
SetDevMode updates development mode in a concurrency-safe way.
func SetGlobalMetricsSink ¶
func SetGlobalMetricsSink(sink MetricsSink)
SetGlobalMetricsSink sets the process-wide metrics sink used as a fallback when no request/session context is available (e.g., off-loop goroutines).
Passing nil disables global metric emission (no-op).
func SetHookSlot ¶
func SetHookSlot(value any)
SetHookSlot stores a value in the current hook slot. Must be called after UseHookSlot returns nil (first render only).
If no owner is set or we're outside render context, this is a no-op.
func SetStrictConcurrency ¶
func SetStrictConcurrency(enabled bool)
SetStrictConcurrency updates strict concurrency mode in a concurrency-safe way.
func SetupOnChange ¶
func SetupOnChange[P any, K comparable](s *SetupCtx[P], key func() K, cb func(next, prev K))
SetupOnChange registers a typed change handler during Setup.
func ShowDefaultPersistBanner ¶
func ShowDefaultPersistBanner(err *PersistBudgetError)
ShowDefaultPersistBanner triggers the default banner for a persist error.
func TestBatch ¶
TestBatch runs fn inside both a session loop and a batch context. Use this when testing batched signal updates.
Example:
func TestBatchedUpdates(t *testing.T) {
a := NewSignal(0)
b := NewSignal(0)
listener := newTestListener()
WithListener(listener, func() {
_ = a.Get()
_ = b.Get()
})
TestBatch(t, func() {
a.Set(1)
b.Set(2)
})
// Listener notified once (batched), not twice
if listener.getDirtyCount() != 1 {
t.Fatal("expected single batched notification")
}
}
func TestDevMode ¶
TestDevMode runs fn with DevMode enabled, ensuring write violations panic with descriptive messages instead of being silently dropped.
Example:
func TestOffLoopWritePanics(t *testing.T) {
TestDevMode(t, func() {
defer func() {
if r := recover(); r == nil {
t.Fatal("expected panic for off-loop write")
}
}()
sig := NewSignal(0)
sig.Set(1) // This should panic
})
}
func TestProdMode ¶
TestProdMode runs fn with DevMode disabled, simulating production behavior where write violations are silently dropped (with logging).
Example:
func TestOffLoopWriteDropped(t *testing.T) {
TestProdMode(t, func() {
sig := NewSignal(42)
sig.Set(100) // Silently dropped (not on session loop)
if sig.Get() != 42 {
t.Fatal("expected write to be dropped")
}
})
}
func TestSessionLoop ¶
TestSessionLoop runs fn on a simulated session loop context. Use this in tests when you need to write signals, as production code does via event handlers.
Signal reads (Get/Peek) do not require TestSessionLoop and can be called from anywhere.
Example:
func TestCounter(t *testing.T) {
count := NewSignal(0)
TestSessionLoop(t, func() {
count.Set(42)
})
if count.Get() != 42 {
t.Fatal("expected 42")
}
}
Multiple writes can be batched in a single TestSessionLoop call:
TestSessionLoop(t, func() {
count.Set(1)
name.Set("Alice")
items.Set([]int{1, 2, 3})
})
func TestSetup ¶
TestSetup runs fn in a setup context inside a session loop. Use this when testing setup-phase behavior.
Example:
func TestSetupPhase(t *testing.T) {
TestSetup(t, func() {
// Setup-phase code here
if !isInSetup() {
t.Fatal("expected to be in setup")
}
})
}
func TestWithOwner ¶
TestWithOwner runs fn with the specified owner as the current owner, inside a session loop context. Use this when testing code that creates signals/effects that should belong to a specific owner.
Example:
func TestOwnershipHierarchy(t *testing.T) {
parent := NewOwner()
var child *Signal[int]
TestWithOwner(t, parent, func() {
child = NewSignal(0)
})
// child is now owned by parent
}
func TrackHook ¶
func TrackHook(ht HookType)
TrackHook records a hook call for the current owner. This is used by feature packages (resource, form, urlparam) to participate in hook-order validation during dev mode.
External packages should call this at the beginning of their hook constructors:
func UseForm[T any](initial T) *Form[T] {
vango.TrackHook(vango.HookForm)
// ... rest of implementation
}
If no owner is set (outside of render context), this is a no-op.
func Tx ¶
func Tx(fn func())
Tx runs fn as a transaction, grouping all signal updates. This is an alias for Batch() that aligns with the transaction terminology used in the spec (§3.9.4 and §7).
All signal updates within the transaction are collected, deduplicated, and notifications only fire when the transaction completes.
Example:
Tx(func() {
user.Set(newUser)
profile.Set(newProfile)
settings.Set(newSettings)
})
// Single re-render with all changes
func TxNamed ¶
func TxNamed(name string, fn func())
TxNamed runs fn as a named transaction for debugging and tracing. The transaction name is logged in debug mode for observability.
This is useful for understanding which transactions trigger re-renders during development and for production tracing.
Example:
TxNamed("user-profile-update", func() {
user.Set(newUser)
profile.Set(newProfile)
})
// Debug output: [TX] user-profile-update start/end
func Untracked ¶
func Untracked(fn func())
Untracked runs a function without tracking signal reads as dependencies. This is useful when you need to read a signal's value without creating a subscription.
Example:
Untracked(func() {
// Reading count here won't subscribe the current component
value := count.Get()
fmt.Println("Current value:", value)
})
Note: For single signal reads, use signal.Peek() instead which is more efficient and clearer in intent.
func UntrackedGet ¶
UntrackedGet reads a signal's value without creating a dependency. This is a convenience function equivalent to signal.Peek().
func UseHookSlot ¶
func UseHookSlot() any
UseHookSlot returns stable hook state from the current owner. On first render, returns nil (caller should create value and call SetHookSlot). On subsequent renders, returns the previously stored value.
This provides stable identity for hooks (like URLParam, Resource) across renders.
Usage pattern:
func SomeHook[T any]() *T {
slot := vango.UseHookSlot()
if slot != nil {
return slot.(*T) // Subsequent render
}
instance := &T{...} // First render
vango.SetHookSlot(instance)
return instance
}
If no owner is set or we're outside render context, returns nil.
func WithCtx ¶
func WithCtx(c any, fn func())
WithCtx runs a function with the specified runtime context. This is used by the server to establish context during event handling and component rendering.
Example (internal use by server):
WithCtx(ctx, func() {
// UseCtx() will return ctx here
component.Render()
})
func WithListener ¶
func WithListener(l Listener, fn func())
WithListener runs a function with the specified listener for tracking. This is used internally to set up dependency tracking during rendering.
func WithOwner ¶
func WithOwner(owner *Owner, fn func())
WithOwner runs a function with the specified owner as the current owner.
This is an internal wiring utility used by the framework when work executes outside the normal component render/effect lifecycle and still needs to attribute reactive allocations to a specific owner.
Application code should not rely on this. Vango components must not spawn goroutines; use Actions/Resources and framework-managed effect helpers (GoLatest/Interval/Timeout/Subscribe) instead.
Example:
WithOwner(parentOwner, func() {
// Signals created here belong to parentOwner
signal := newSignal(0)
_ = signal
})
func WithRenderAllocationsDisabled ¶
func WithRenderAllocationsDisabled(fn func())
WithRenderAllocationsDisabled runs a function with render allocations forbidden.
func WithSessionLoop ¶
func WithSessionLoop(fn func())
WithSessionLoop marks execution as running on the session loop. This is used by the server runtime and tests to enforce single-writer rules.
func WithTxTraceHook ¶
func WithTxTraceHook(ctx context.Context, hook TxTraceHook) context.Context
WithTxTraceHook attaches a TxTraceHook to a context for TxNamed to use. This is intended for middleware (e.g., OpenTelemetry) to integrate without introducing a dependency from core vango to tracing libraries.
func WithWorkerContext ¶
func WithWorkerContext(kind WorkerKind, meta *primitiveMetadata, runtimeCtx Ctx, fn func())
WithWorkerContext runs fn with the goroutine marked as executing framework worker code. This must be used by Vango internals when running Resource loaders and Action work.
Types ¶
type Action ¶
Action is the structured primitive for async mutations. It bundles loading/error/success state, cancellation, and dispatch into a standard, auditable unit allocated during Setup.
func SetupAction ¶
func SetupAction[P any, A any, R any]( s *SetupCtx[P], work func(ctx context.Context, arg A) (R, error), opts ...ActionOption, ) *Action[A, R]
SetupAction creates an action during Setup.
func (*Action[A, R]) Match ¶
func (a *Action[A, R]) Match(handlers ...ActionHandler[A, R]) *vdom.VNode
Match renders different content based on the action state.
func (*Action[A, R]) Metadata ¶
func (a *Action[A, R]) Metadata() vruntime.PrimitiveMetadata
Metadata returns identity metadata for the primitive.
func (*Action[A, R]) Reset ¶
func (a *Action[A, R]) Reset()
Reset sets the Action back to ActionIdle and clears stored result/error.
func (*Action[A, R]) Result ¶
Result returns the last successful result and true, or zero value and false if no success has occurred yet.
func (*Action[A, R]) Run ¶
Run starts the async operation with the given argument. Returns true if the call was accepted (started or queued), false if rejected.
Spec-aligned contract (Developer Guide v1):
- MUST be called on the session loop (event handler, effect, or Dispatch callback)
- MUST NOT be called during render or setup
- Work runs off-loop and MUST respect ctx cancellation
Behavior depends on concurrency policy:
- CancelLatest: Cancels any in-flight work, starts new. Returns true.
- DropWhileRunning: Ignores call if already running. Returns false if dropped.
- Queue: Queues the call if running. Returns false if queue is full.
func (*Action[A, R]) State ¶
func (a *Action[A, R]) State() ActionState
State returns the current ActionState. This is reactive - reading it inside an Effect will subscribe to changes.
type ActionHandler ¶
ActionHandler handles a specific Action state.
func OnActionError ¶
OnActionError handles the Error state.
func OnActionIdle ¶
func OnActionIdle[A any, R any](fn func() *vdom.VNode) ActionHandler[A, R]
OnActionIdle handles the Idle state.
func OnActionRunning ¶
func OnActionRunning[A any, R any](fn func() *vdom.VNode) ActionHandler[A, R]
OnActionRunning handles the Running state.
func OnActionSuccess ¶
func OnActionSuccess[A any, R any](fn func(R) *vdom.VNode) ActionHandler[A, R]
OnActionSuccess handles the Success state.
type ActionOption ¶
type ActionOption interface {
// contains filtered or unexported methods
}
ActionOption is an option for configuring an Action.
func ActionOnError ¶
func ActionOnError(fn func(error)) ActionOption
ActionOnError registers a callback that runs when the action fails. The callback runs on the session loop and receives the error.
func ActionOnSuccess ¶
func ActionOnSuccess(fn func(any)) ActionOption
ActionOnSuccess registers a callback that runs on successful completion. The callback runs on the session loop and receives the result.
Note: Due to Go's type system limitations, this version takes func(any). For type-safe callbacks, use the OnSuccess method on the Action directly or cast the result in the callback.
func ActionTxName ¶
func ActionTxName(name string) ActionOption
ActionTxName sets the transaction name for observability. State transitions will appear in DevTools as:
- Action:<name>:running
- Action:<name>:success
- Action:<name>:error
Without this option, a default name based on component/file is used.
func CancelLatest ¶
func CancelLatest() ActionOption
CancelLatest returns an option that cancels prior in-flight work on new Run. This is the default concurrency policy.
When Run is called while another operation is running:
- The prior operation is cancelled via context cancellation
- The new operation starts immediately
- Run returns true
func DropWhileRunning ¶
func DropWhileRunning() ActionOption
DropWhileRunning returns an option that ignores Run while an operation is running.
When Run is called while another operation is running:
- The call is ignored (no-op)
- Run returns false
func OnActionRejected ¶
func OnActionRejected(fn func(ActionRejection)) ActionOption
OnActionRejected registers a callback that runs when Action.Run is rejected by a concurrency policy (e.g., queue full, drop-while-running).
This callback is invoked on the session loop and does not affect ActionState.
func OnActionStart ¶
func OnActionStart(fn func()) ActionOption
OnActionStart registers a callback that runs when the action starts. The callback runs on the session loop (inside a Dispatch).
func Queue ¶
func Queue(maxQueue int) ActionOption
Queue returns an option that queues Run calls and executes them sequentially.
When Run is called while another operation is running:
- If queue has room, the call is queued. Run returns true.
- If queue is full, the call is rejected. Run returns false.
maxQueue specifies the maximum number of queued calls (must be > 0).
type ActionPanicError ¶
type ActionPanicError struct {
Value any
}
ActionPanicError wraps a panic value captured from Action work. It implements errors.Is(err, ErrActionPanicked).
func (*ActionPanicError) Error ¶
func (e *ActionPanicError) Error() string
func (*ActionPanicError) Is ¶
func (e *ActionPanicError) Is(target error) bool
func (*ActionPanicError) Unwrap ¶
func (e *ActionPanicError) Unwrap() error
type ActionRejection ¶
type ActionRejection struct {
Reason ActionRejectionReason
When time.Time
}
ActionRejection is passed to OnActionRejected callbacks. It intentionally does not include the input argument to avoid memory/PII footguns.
type ActionRejectionReason ¶
type ActionRejectionReason string
ActionRejectionReason describes why an Action.Run call was rejected. Rejections are admission-control events (policy/disposal), not work outcomes.
const ( ActionRejectQueueFull ActionRejectionReason = "queue_full" ActionRejectDropWhileRunning ActionRejectionReason = "dropped_while_running" )
type ActionState ¶
type ActionState int
ActionState represents the current state of an Action.
const ( // ActionIdle is the initial state before any Run call. ActionIdle ActionState = iota // ActionRunning indicates an async operation is in progress. ActionRunning // ActionSuccess indicates the last operation completed successfully. ActionSuccess // ActionError indicates the last operation failed. ActionError )
func (ActionState) String ¶
func (s ActionState) String() string
String returns a human-readable name for the action state.
type AnimationEvent ¶
type AnimationEvent struct {
// Name of the CSS animation
AnimationName string
// Time in seconds since the animation started
ElapsedTime float64
// Pseudo-element the animation runs on (e.g., "::before")
PseudoElement string
}
AnimationEvent represents a CSS animation event. Per spec section 3.9.3, lines 1230-1234.
type BannerSpec ¶
BannerSpec defines the session refresh banner content.
func DefaultBannerSpec ¶
func DefaultBannerSpec(devMode bool, reason protocol.SchemaRefreshReason) BannerSpec
DefaultBannerSpec returns the default banner configuration.
type BoolSignal
deprecated
BoolSignal wraps Signal[bool] with convenience methods for boolean operations.
Deprecated: Use setup.Signal inside vango.Setup. Signal[bool] now has Toggle(), SetTrue(), and SetFalse() methods directly available.
// Old: visible := vango.NewBoolSignal(false) visible.Toggle() // New: visible := setup.Signal(&s, false) visible.Toggle()
func NewBoolSignal
deprecated
func NewBoolSignal(initial bool) *BoolSignal
NewBoolSignal creates a new BoolSignal with the given initial value.
Deprecated: Use setup.Signal inside vango.Setup. Signal[bool] now has Toggle(), SetTrue(), and SetFalse() methods directly available.
type BudgetExceededMode ¶
type BudgetExceededMode int
BudgetExceededMode determines behavior when a storm budget is exceeded. (Re-exported from server/config.go for convenience)
const ( // BudgetModeThrottle drops excess operations silently (default). BudgetModeThrottle BudgetExceededMode = iota // BudgetModeTripBreaker pauses effect execution until cleared. BudgetModeTripBreaker )
type BudgetKind ¶
type BudgetKind int
BudgetKind identifies which budget was exceeded.
const ( BudgetKindPrimitive BudgetKind = iota BudgetKindSession )
func (BudgetKind) String ¶
func (k BudgetKind) String() string
type BudgetScope ¶
type BudgetScope int
BudgetScope indicates which persistence scope a primitive belongs to.
const ( BudgetScopeLocal BudgetScope = iota BudgetScopeSession BudgetScopeGlobal )
type BudgetStats ¶
type BudgetStats struct {
ResourceStartsInWindow int
ActionStartsInWindow int
GoLatestStartsInWindow int
EffectRunsThisTick int
}
Stats returns current budget usage statistics.
type BudgetTracker ¶
type BudgetTracker struct {
// contains filtered or unexported fields
}
BudgetTracker tracks persisted state sizes for budget enforcement. It is safe for concurrent use.
func NewBudgetTracker ¶
func NewBudgetTracker(cfg StateBudgetConfig, c codec.Codec, devMode bool) *BudgetTracker
NewBudgetTracker creates a BudgetTracker with the given configuration.
func (*BudgetTracker) CheckAndRecord ¶
func (bt *BudgetTracker) CheckAndRecord(scope BudgetScope, sessionID, stableID, debugName string, newBytes int64) *PersistBudgetError
CheckAndRecord validates a write against budgets and updates tracking.
func (*BudgetTracker) EncodedSize ¶
func (bt *BudgetTracker) EncodedSize(value any) (int64, error)
EncodedSize returns the encoded size of a value using the persistence codec.
func (*BudgetTracker) GetSessionSize ¶
func (bt *BudgetTracker) GetSessionSize(sessionID string) int64
GetSessionSize returns the tracked size for a session.
func (*BudgetTracker) RecordExisting ¶
func (bt *BudgetTracker) RecordExisting(sessionID, stableID string, bytes int64)
RecordExisting stores a previously persisted size without budget checks.
func (*BudgetTracker) RemoveSession ¶
func (bt *BudgetTracker) RemoveSession(sessionID string)
RemoveSession cleans up tracking for a closed session.
func (*BudgetTracker) SetMetricsCallbacks ¶
func (bt *BudgetTracker) SetMetricsCallbacks( onWrite func(scope BudgetScope, stableID string, bytes int64), onRejection func(reason string, stableID string, err *PersistBudgetError), )
SetMetricsCallbacks configures metrics collection. onWrite receives the scope, stable ID, and bytes written. onRejection receives a normalized reason and stable ID plus the error.
type Cleanup ¶
type Cleanup func()
Cleanup is a function returned by effects to clean up resources. It is called before the effect re-runs and when the effect is disposed.
func GoLatest ¶
func GoLatest[K comparable, R any]( key K, work func(ctx context.Context, key K) (R, error), apply func(result R, err error), opts ...GoLatestOption, ) Cleanup
GoLatest is the standard helper for async integration work inside Effect. It handles key coalescing, stale suppression, cancellation, and dispatch.
Key semantics:
- Same key as previous call: No new work starts (existing work continues)
- Different key: Cancels prior work, starts new work
- Use GoLatestForceRestart() to restart even with same key
MUST be called inside an Effect:
s.Effect(func() vango.Cleanup {
q := query.Get()
return vango.GoLatest(q,
func(ctx context.Context, q string) ([]User, error) {
return api.SearchUsers(ctx, q)
},
func(users []User, err error) {
results.Set(users)
},
)
})
See SPEC_ADDENDUM.md §A.2.3.
func Interval ¶
func Interval(d time.Duration, fn func(), opts ...IntervalOption) Cleanup
Interval schedules periodic ticks that execute fn on the session loop. It handles cleanup automatically - the returned Cleanup stops future ticks.
By default, the first tick occurs after duration d. Use IntervalImmediate() to trigger the first tick immediately.
MUST be called inside an Effect and the returned Cleanup SHOULD be returned from that Effect:
s.Effect(func() vango.Cleanup {
return vango.Interval(time.Second, func() {
counter.Inc()
})
})
See SPEC_ADDENDUM.md §A.2.1.
func Subscribe ¶
func Subscribe[T any](stream Stream[T], fn func(T), opts ...SubscribeOption) Cleanup
Subscribe connects to an event stream and invokes fn for each message on the session loop. The returned Cleanup unsubscribes from the stream.
MUST be called inside an Effect and the returned Cleanup SHOULD be returned from that Effect:
s.Effect(func() vango.Cleanup {
return vango.Subscribe(ws.Messages, func(msg Message) {
messages.Append(msg)
})
})
See SPEC_ADDENDUM.md §A.2.2.
func Timeout ¶
func Timeout(d time.Duration, fn func(), opts ...TimeoutOption) Cleanup
Timeout creates a one-shot timer that executes fn after duration d. Returns a Cleanup that cancels the timer if called before it fires.
This is a simpler alternative to Interval for single delayed operations:
s.Effect(func() vango.Cleanup {
return vango.Timeout(5*time.Second, func() {
showTooltip.Set(true)
})
})
type Component ¶
Component is an alias for vdom.Component for convenience. Components are anything that can render to a VNode.
func DefaultPersistErrorBanner ¶
func DefaultPersistErrorBanner() Component
DefaultPersistErrorBanner renders the default banner component.
type ConcurrencyPolicy ¶
type ConcurrencyPolicy int
ConcurrencyPolicy defines how an Action handles concurrent Run calls.
const ( // PolicyCancelLatest cancels prior in-flight work when Run is called again. // This is the default policy. PolicyCancelLatest ConcurrencyPolicy = iota // PolicyDropWhileRunning ignores Run calls while work is in progress. PolicyDropWhileRunning // PolicyQueue queues Run calls and executes them sequentially. PolicyQueue )
type Context ¶
type Context[T any] struct { // contains filtered or unexported fields }
Context provides dependency injection through the component tree. Create a context with CreateContext, provide values with Provider, and consume values with Use.
Provider scoping (normative): Provider() creates a new owner scope (component boundary) so the provided value is only visible to descendants of the Provider, not to sibling components.
Reactivity (normative): Use() is a reactive hook that subscribes the calling component to the context value. When a Provider re-renders with a new value, all components that called Use() on that context will be re-rendered. See VANGO_ARCHITECTURE_AND_GUIDE.md §3.1.3 and §3.9.10.
Example:
var ThemeContext = vango.CreateContext("light")
func App() vango.Component {
return vango.Setup(vango.NoProps{}, func(s vango.SetupCtx[vango.NoProps]) vango.RenderFn {
theme := setup.Signal(&s, "dark")
return func() *vango.VNode {
return ThemeContext.Provider(theme.Get(),
Header(),
Main(),
)
}
})
}
func Button() *vango.VNode {
theme := ThemeContext.Use() // Subscribes to changes
return vdom.Button(vdom.Class("btn-" + theme))
}
func CreateContext ¶
CreateContext creates a new context with the given default value. The default value is returned by Use() when no Provider is found in the component tree.
Example:
var ThemeContext = vango.CreateContext("light")
var UserContext = vango.CreateContext[*User](nil)
func (*Context[T]) Default ¶
func (c *Context[T]) Default() T
Default returns the default value for this context.
func (*Context[T]) Provider ¶
Provider wraps children with this context's value. Descendant components can access the value via Use().
Provider creates a new component boundary (owner scope) so the context value is only visible to descendants, not siblings. This is the proper scoping behavior per the spec.
The provider is reactive: when the value changes and the parent component re-renders, all descendants that called Use() will also re-render.
Example:
func App() vango.Component {
return vango.Setup(vango.NoProps{}, func(s vango.SetupCtx[vango.NoProps]) vango.RenderFn {
theme := setup.Signal(&s, "dark")
return func() *vango.VNode {
return ThemeContext.Provider(theme.Get(),
Header(),
Main(),
Footer(),
)
}
})
}
func (*Context[T]) Use ¶
func (c *Context[T]) Use() T
Use retrieves the context value from the nearest Provider ancestor. If no Provider is found, returns the default value.
This is a reactive hook: it subscribes the calling component to the context value. When the Provider re-renders with a new value, this component will also re-render.
This MUST be called unconditionally during render (hook-order semantics). See §3.1.3 Hook-Order Semantics.
Example:
func Button() *vango.VNode {
theme := ThemeContext.Use()
return vdom.Button(vdom.Class("btn-" + theme))
}
type Ctx ¶
type Ctx interface {
// Dispatch queues a function to run on the session's event loop.
// This is safe to call from any goroutine and is the correct way to
// update signals from asynchronous operations.
//
// Prefer Vango primitives (Action/Resource/GoLatest/Subscribe/Interval/Timeout)
// over ad hoc concurrency. Dispatch is primarily for integrating with
// external libraries that invoke callbacks off the session loop.
//
// Example (callback invoked off-loop by a library):
//
// unsubscribe := emitter.OnEvent(func(ev Event) {
// ctx.Dispatch(func() {
// lastEvent.Set(ev)
// })
// })
// defer unsubscribe()
Dispatch(fn func())
// StdContext returns the standard library context with trace propagation.
// Use this when calling external services or database drivers.
//
// Example:
// row := db.QueryRowContext(ctx.StdContext(), "SELECT * FROM users WHERE id = $1", userID)
StdContext() context.Context
// StormBudget returns the storm budget checker for this session.
// Used by primitives (Action, Resource, GoLatest) to check rate limits.
// Returns nil if storm budgets are not configured.
//
// See SPEC_ADDENDUM.md §A.4 for storm budget configuration.
StormBudget() StormBudgetChecker
// Session returns the active session, if any.
// Typed session keys use this to persist state.
Session() Session
}
Ctx is the runtime context interface available during render, effects, and event handlers. It provides access to the current request, session, and utility methods.
Use UseCtx() to obtain the current context within a component.
func UseCtx ¶
func UseCtx() Ctx
UseCtx returns the current runtime context for the active session tick. It MUST only be called during a component render, effect, or event handler.
Returns nil if called outside of a render/effect/handler context.
Example:
func MyComponent() vango.Component {
return vango.Setup(vango.NoProps{}, func(s vango.SetupCtx[vango.NoProps]) vango.RenderFn {
type User struct {
Name string
}
users := map[int]User{
1: {Name: "Ada"},
2: {Name: "Grace"},
}
loadUser := func(ctx context.Context, id int) (User, error) {
select {
case <-ctx.Done():
return User{}, ctx.Err()
case <-time.After(50 * time.Millisecond):
}
u, ok := users[id]
if !ok {
return User{}, fmt.Errorf("user %d: %w", id, errors.New("not found"))
}
return u, nil
}
userID := setup.Signal(&s, 1)
user := setup.Signal(&s, User{})
loadErr := setup.Signal(&s, error(nil))
s.Effect(func() vango.Cleanup {
id := userID.Get()
return vango.GoLatest(id, loadUser, func(u User, err error) {
loadErr.Set(err)
if err == nil {
user.Set(u)
}
})
})
return func() *vango.VNode {
if err := loadErr.Get(); err != nil {
return Div(Text(err.Error()))
}
return Div(Text(user.Get().Name))
}
})
}
type DebugConfig ¶
type DebugConfig struct {
// IncludeSourceLocations includes file:line in debug messages.
// Useful for tracing signal/effect creation locations.
// Default: false (for performance).
IncludeSourceLocations bool
// LogRawKeys logs signal persist keys and internal identifiers.
// Useful for debugging state persistence issues.
// Default: false.
LogRawKeys bool
// LogEffectRuns logs each effect run with timing information.
// Useful for debugging performance issues.
// Default: false.
LogEffectRuns bool
// LogStormBudget logs when storm budgets are checked or exceeded.
// Useful for tuning budget limits.
// Default: false.
LogStormBudget bool
}
DebugConfig controls debugging features for development. These settings affect logging and error messages.
func DefaultDebugConfig ¶
func DefaultDebugConfig() DebugConfig
DefaultDebugConfig returns a DebugConfig with all debugging disabled. Enable individual options as needed for development.
type Dependency ¶
type Dependency interface {
// ID is a stable, process-local identifier for this dependency.
ID() uint64
// Unsubscribe removes the given listener from this dependency.
Unsubscribe(listener Listener)
}
Dependency is a reactive source that can be unsubscribed from.
This is a framework-internal interface primarily used by the server runtime to track per-render dependencies for components so that stale subscriptions can be removed when a component stops reading a dependency.
It is intentionally narrow: user code typically never needs to interact with Dependency values directly.
type DependencyTracker ¶
type DependencyTracker interface {
TrackDependency(dep Dependency)
}
DependencyTracker is implemented by listeners (typically component instances) that want to record which dependencies they read during the current tracking scope (usually a render). The runtime uses this to unsubscribe from stale dependencies between renders.
type DragEvent ¶
type DragEvent struct {
// Position relative to viewport
ClientX int
ClientY int
// Modifier keys
CtrlKey bool
ShiftKey bool
AltKey bool
MetaKey bool
// contains filtered or unexported fields
}
DragEvent represents a drag-and-drop event. Per spec section 3.9.3, lines 1181-1200.
type DropEvent ¶
type DropEvent = DragEvent
DropEvent is an alias for DragEvent used on drop targets. Per spec section 3.9.3, lines 1197-1199.
type Effect ¶
type Effect struct {
// contains filtered or unexported fields
}
Effect represents a reactive side effect that runs when its dependencies change. Effects are created using SetupCtx.Effect and are automatically tracked for dependencies during their execution.
Effects run after commit when created during render, and re-run whenever any signal or memo they read during execution changes. If created outside render, they run immediately. They can return a Cleanup function that will be called before the effect re-runs or when the effect is disposed.
func (*Effect) GetCallSiteData ¶
GetCallSiteData retrieves stored state for a specific call-site index. Returns nil if no state has been stored for this call-site. Used by effect helpers like GoLatest to maintain state across effect reruns.
func (*Effect) ID ¶
ID returns the unique identifier for this effect. Implements the Listener interface.
func (*Effect) MarkDirty ¶
func (e *Effect) MarkDirty()
MarkDirty marks the effect as needing to re-run. Implements the Listener interface.
func (*Effect) Metadata ¶
func (e *Effect) Metadata() vruntime.PrimitiveMetadata
Metadata returns identity metadata for the primitive.
func (*Effect) SetCallSiteData ¶
SetCallSiteData stores state for a specific call-site index. Used by effect helpers like GoLatest to maintain state across effect reruns.
type EffectOption ¶
type EffectOption interface {
// contains filtered or unexported methods
}
EffectOption is an option for configuring an Effect.
func AllowWrites ¶
func AllowWrites() EffectOption
AllowWrites marks an effect as intentionally performing signal writes. Without this option, signal writes during the effect body will trigger a warning (StrictEffectWarn) or panic (StrictEffectPanic).
Most patterns don't need this - writes inside ctx.Dispatch callbacks (as with Interval, Subscribe, GoLatest) are not effect-time writes.
Use this only for rare cases like synchronous initialization:
s.Effect(func() vango.Cleanup {
syncedValue.Set(legacySystem.ReadCurrentSync())
return nil
}, vango.AllowWrites())
See SPEC_ADDENDUM.md §A.3.
func EffectTxName ¶
func EffectTxName(name string) EffectOption
EffectTxName sets the transaction name for the effect. This name appears in warnings and DevTools entries for this effect. It does NOT propagate to helper transactions (Interval/Subscribe/GoLatest).
type EventRateLimitConfig ¶
EventRateLimitConfig configures token bucket rate limiting for events. RatePerSecond <= 0 disables rate limiting.
func DefaultDOMEventRateLimitConfig ¶
func DefaultDOMEventRateLimitConfig() *EventRateLimitConfig
DefaultDOMEventRateLimitConfig returns a default rate limit for standard DOM events. Designed to allow 120Hz input while still providing DoS backpressure.
func DefaultEventRateLimitConfig ¶
func DefaultEventRateLimitConfig() *EventRateLimitConfig
DefaultEventRateLimitConfig returns a conservative default rate limit.
type Float64Signal
deprecated
Float64Signal wraps Signal[float64] with convenience methods for float operations.
Deprecated: Use setup.Signal inside vango.Setup. Signal[float64] now has Add(), Sub(), Mul(), and Div() methods directly available.
func NewFloat64Signal
deprecated
func NewFloat64Signal(initial float64) *Float64Signal
NewFloat64Signal creates a new Float64Signal with the given initial value.
Deprecated: Use setup.Signal inside vango.Setup. Signal[float64] now has Add(), Sub(), Mul(), and Div() methods directly available.
func (*Float64Signal) Mul ¶
func (s *Float64Signal) Mul(n float64)
Mul multiplies by the given value.
func (*Float64Signal) Multiply ¶
func (s *Float64Signal) Multiply(n float64)
Multiply is an alias for Mul. Deprecated: use Mul instead.
type FormData ¶
type FormData struct {
// contains filtered or unexported fields
}
FormData represents submitted form data. Per spec section 3.9.3, lines 1169-1179.
func NewFormData ¶
NewFormData creates a new FormData from a map of values.
func NewFormDataFromSingle ¶
NewFormDataFromSingle creates FormData from a single-value map. This is for backward compatibility with the old map[string]string format.
func (FormData) All ¶
All returns all form fields as a map. For fields with multiple values, only the first value is returned.
type GlobalBroadcastBackend ¶
type GlobalBroadcastBackend interface {
Publish(ctx context.Context, channel string, data []byte) error
Subscribe(ctx context.Context, channel string) (<-chan []byte, error)
}
GlobalBroadcastBackend broadcasts updates to other instances.
func NewMemoryPubSub ¶
func NewMemoryPubSub() GlobalBroadcastBackend
NewMemoryPubSub creates an in-memory broadcast backend. Intended for tests or single-process development.
func NewRedisPubSub ¶
func NewRedisPubSub(client *redis.Client) GlobalBroadcastBackend
NewRedisPubSub creates a Redis-backed broadcast backend.
type GlobalPersistenceBackend ¶
type GlobalPersistenceBackend interface {
Get(ctx context.Context, key string) ([]byte, error)
Set(ctx context.Context, key string, value []byte) error
// SetManyAtomic persists a batch of keys atomically.
//
// Implementations MUST commit the provided batch atomically. Callers are
// responsible for ensuring any backend-specific constraints are satisfied
// by the keys (e.g. Redis Cluster hash slot co-location).
SetManyAtomic(ctx context.Context, values map[string][]byte) error
Delete(ctx context.Context, key string) error
}
GlobalPersistenceBackend stores global signal values.
type GlobalSignalStore ¶
type GlobalSignalStore struct {
// contains filtered or unexported fields
}
GlobalSignalStore manages global signals across all sessions.
func NewGlobalSignalStore ¶
func NewGlobalSignalStore(backend GlobalPersistenceBackend, pubsub GlobalBroadcastBackend, opts ...GlobalSignalStoreOption) *GlobalSignalStore
NewGlobalSignalStore creates a global signal store.
func (*GlobalSignalStore) ApplyEncoded ¶
func (gs *GlobalSignalStore) ApplyEncoded(stableID string, encoded []byte) (bool, error)
ApplyEncoded applies an encoded global signal update on the session loop.
func (*GlobalSignalStore) GetOrCreateSignal ¶
func (gs *GlobalSignalStore) GetOrCreateSignal( ctx context.Context, stableID string, fingerprint codec.Fingerprint, initializer func() any, decode func([]byte) (any, error), createSignal func(any) any, ) (any, error)
GetOrCreate retrieves or creates a global signal.
func (*GlobalSignalStore) RefreshAll ¶
func (gs *GlobalSignalStore) RefreshAll(ctx context.Context) ([]GlobalSignalUpdate, error)
RefreshAll fetches latest values for known global signals.
func (*GlobalSignalStore) Set ¶
func (gs *GlobalSignalStore) Set(stableID string, value any) error
Set updates a global signal value and persists it.
func (*GlobalSignalStore) SetBroadcastHandler ¶
func (gs *GlobalSignalStore) SetBroadcastHandler(ctx context.Context, handler func(stableID string, encoded []byte))
SetBroadcastHandler registers a handler for pubsub-delivered updates. The handler is invoked with the stable ID and encoded payload.
func (*GlobalSignalStore) SetBudgetTracker ¶
func (gs *GlobalSignalStore) SetBudgetTracker(tracker *BudgetTracker)
SetBudgetTracker sets the budget tracker for global signals.
type GlobalSignalStoreOption ¶
type GlobalSignalStoreOption interface {
// contains filtered or unexported methods
}
func WithGlobalSignalSecrets ¶
func WithGlobalSignalSecrets(secret []byte, previous []byte) GlobalSignalStoreOption
WithGlobalSignalSecrets configures HMAC secrets for global signal persistence. When a backend or pubsub is configured, secrets are required for integrity.
type GlobalSignalUpdate ¶
GlobalSignalUpdate contains a refreshed global signal payload.
type GoLatestOption ¶
type GoLatestOption interface {
// contains filtered or unexported methods
}
GoLatestOption is an option for configuring GoLatest.
func GoLatestForceRestart ¶
func GoLatestForceRestart() GoLatestOption
GoLatestForceRestart causes work to restart even when the key is unchanged. By default, same key = no new work (existing work continues).
func GoLatestTxName ¶
func GoLatestTxName(name string) GoLatestOption
GoLatestTxName sets the transaction name for observability. Work will appear in DevTools as GoLatest:<name>.
type HTTPError ¶
type HTTPError struct {
Code int // HTTP status code (e.g., 400, 403, 404, 500)
Message string // Error message to return to client
Err error // Optional underlying error
}
HTTPError represents an HTTP error with a status code and message. It implements the error interface and can be returned from API handlers to send appropriate HTTP status codes to clients.
func BadRequest ¶
BadRequest creates a 400 Bad Request error. Use this when the client sent invalid data.
Example:
if err := validate(input); err != nil {
return nil, vango.BadRequest(err)
}
func BadRequestf ¶
BadRequestf creates a 400 Bad Request error with a formatted message.
func Conflict ¶
Conflict creates a 409 Conflict error. Use this when the request conflicts with the current state.
func Forbidden ¶
Forbidden creates a 403 Forbidden error. Use this when the user is authenticated but lacks permission.
Example:
if !user.HasRole("admin") {
return nil, vango.Forbidden()
}
func InternalError ¶
InternalError creates a 500 Internal Server Error. Use this for unexpected server errors. Consider logging the underlying error.
func NotFound ¶
NotFound creates a 404 Not Found error. Use this when the requested resource doesn't exist.
func ServiceUnavailable ¶
ServiceUnavailable creates a 503 Service Unavailable error. Use this when the server is temporarily unable to handle requests.
func Unauthorized ¶
Unauthorized creates a 401 Unauthorized error. Use this when authentication is required but not provided.
func UnprocessableEntity ¶
UnprocessableEntity creates a 422 Unprocessable Entity error. Use this for validation errors on semantically correct but invalid data.
func (*HTTPError) StatusCode ¶
StatusCode returns the HTTP status code for this error.
type Handler ¶
type Handler[T any] interface { // contains filtered or unexported methods }
Handler handles a specific resource state.
func OnLoadingOrPending ¶
OnLoadingOrPending handles both Loading and Pending states.
type HookEvent ¶
type HookEvent struct {
// Name of the hook event
Name string
// Arbitrary data from the client
Data map[string]any
// contains filtered or unexported fields
}
HookEvent represents a client hook event. Per spec section 3.9.3, line 1018.
func (HookEvent) GetStrings ¶
GetStrings returns a []string value from the hook data.
func (HookEvent) Revert ¶
func (h HookEvent) Revert()
Revert sends a revert signal to the client hook. Used for optimistic update rollback.
func (*HookEvent) SetContext ¶
SetContext sets the internal context for the hook event. This is called by the runtime when dispatching hook events.
type HookEventValidator ¶
HookEventValidator validates a hook event payload. Return an error to reject the event.
func HookSchemaValidator ¶
func HookSchemaValidator[T any](validate func(HookEvent, T) error) HookEventValidator
HookSchemaValidator builds a HookEventValidator that decodes hook payload data into a typed schema using strict JSON rules (unknown fields are rejected).
The callback may be nil to run schema decoding only.
type InputEvent ¶
type InputEvent struct {
// Current value of the input
Value string
// Type of input change (e.g., "insertText", "deleteContentBackward")
InputType string
// Data being inserted (if any)
Data string
}
InputEvent represents an input field change event. Per spec section 3.9.3, lines 1131-1133.
type Int64Signal
deprecated
Int64Signal wraps Signal[int64] with convenience methods for integer operations.
Deprecated: Use setup.Signal inside vango.Setup. Signal[int64] now has Inc(), Dec(), Add(), Sub(), Mul(), and Div() methods directly available.
func NewInt64Signal
deprecated
func NewInt64Signal(initial int64) *Int64Signal
NewInt64Signal creates a new Int64Signal with the given initial value.
Deprecated: Use setup.Signal inside vango.Setup. Signal[int64] now has Inc(), Dec(), Add(), Sub(), Mul(), and Div() methods directly available.
func (*Int64Signal) Div ¶
func (s *Int64Signal) Div(n int64)
Div divides by the given value. Note: Integer division truncates toward zero.
type IntSignal
deprecated
IntSignal wraps Signal[int] with convenience methods for integer operations.
Deprecated: Use setup.Signal inside vango.Setup. Signal[int] now has Inc(), Dec(), Add(), Sub(), Mul(), and Div() methods directly available.
// Old: count := vango.NewIntSignal(0) count.Inc() // New: count := setup.Signal(&s, 0) count.Inc()
func NewIntSignal
deprecated
type IntervalOption ¶
type IntervalOption interface {
// contains filtered or unexported methods
}
IntervalOption is an option for configuring Interval.
func IntervalImmediate ¶
func IntervalImmediate() IntervalOption
IntervalImmediate causes the first tick to occur immediately instead of after the duration.
func IntervalTxName ¶
func IntervalTxName(name string) IntervalOption
IntervalTxName sets the transaction name for observability. Ticks will appear in DevTools as Interval:<name>.
type IslandMessage ¶
type IslandMessage struct {
// ID is the island name/module identifier (the value of data-island).
ID string
// HID is the unique instance address (the hydration id of the island boundary element).
// This allows multiple instances with the same ID to coexist on a page.
HID string
Raw json.RawMessage
}
IslandMessage represents a message sent between an island and the server.
type IslandMessageHandler ¶
type IslandMessageHandler func(IslandMessage)
IslandMessageHandler handles messages emitted by client islands.
type IslandMessageValidator ¶
type IslandMessageValidator func(IslandMessage) error
IslandMessageValidator validates an island message payload. Return an error to reject the message.
func IslandSchemaValidator ¶
func IslandSchemaValidator[T any](validate func(IslandMessage, T) error) IslandMessageValidator
IslandSchemaValidator builds an IslandMessageValidator that decodes island message payloads into a typed schema using strict JSON rules.
The callback may be nil to run schema decoding only.
type IslandMessenger ¶
type IslandMessenger interface {
RegisterIslandHandler(id string, handler IslandMessageHandler) func()
SendIslandMessage(id string, payload any) error
SendIslandMessageToHID(hid string, payload any) error
}
IslandMessenger describes session capabilities for island messaging.
type KeyMod ¶
type KeyMod uint8
KeyMod represents keyboard modifier flags for KeyWithModifiers.
type KeyboardEvent ¶
type KeyboardEvent struct {
// The key value (e.g., "Enter", "a", "Escape")
Key string
// The physical key code (e.g., "Enter", "KeyA", "Escape")
Code string
// Modifier keys
CtrlKey bool
ShiftKey bool
AltKey bool
MetaKey bool
// True if key is being held down (auto-repeat)
Repeat bool
// Key location: 0=standard, 1=left, 2=right, 3=numpad
Location int
}
KeyboardEvent represents a keyboard event with key and modifiers. Per spec section 3.9.3, lines 1091-1103.
type Listener ¶
type Listener interface {
// MarkDirty notifies the listener that one of its dependencies has changed.
// For components, this schedules a re-render.
// For memos, this invalidates the cached value.
// For effects, this schedules the effect to re-run.
MarkDirty()
// ID returns a unique identifier for this listener.
// Used for deduplication during batch processing.
ID() uint64
}
Listener is anything that can be notified when a dependency changes. This interface is implemented by components, memos, and effects.
type MapSignal
deprecated
type MapSignal[K comparable, V any] struct { *Signal[map[K]V] }
MapSignal wraps Signal[map[K]V] with convenience methods for map operations.
Deprecated: Use setup.Signal inside vango.Setup. Signal[map[K]V] now has SetKey(), RemoveKey(), UpdateKey(), HasKey(), Clear(), and Len() methods directly available.
Note: MapSignal[K,V] provides type-safe methods (e.g., SetKey(key K, value V)) while the Signal[T] methods use any (e.g., SetKey(key, value any)). Use MapSignal[K,V] if you prefer compile-time type safety over the unified API.
// Old:
users := vango.NewMapSignal(map[string]User{})
users.SetKey("alice", alice)
// New:
users := setup.Signal(&s, map[string]User{})
users.SetKey("alice", alice) // Note: uses 'any' parameters
func NewMapSignal
deprecated
func NewMapSignal[K comparable, V any](initial map[K]V) *MapSignal[K, V]
NewMapSignal creates a new MapSignal with the given initial value. If initial is nil, creates an empty map.
Deprecated: Use setup.Signal inside vango.Setup. Signal[map[K]V] now has map convenience methods directly available. MapSignal[K,V] is retained for type-safe map operations if preferred.
func (*MapSignal[K, V]) Clear ¶
func (s *MapSignal[K, V]) Clear()
Clear removes all keys from the map.
func (*MapSignal[K, V]) DeleteKey ¶
func (s *MapSignal[K, V]) DeleteKey(key K)
DeleteKey removes a key from the map. Deprecated: use RemoveKey instead.
func (*MapSignal[K, V]) GetKey ¶
GetKey returns the value for a key. This reads the signal and creates a dependency.
func (*MapSignal[K, V]) HasKey ¶
HasKey returns true if the key exists in the map. This reads the signal and creates a dependency.
func (*MapSignal[K, V]) Keys ¶
func (s *MapSignal[K, V]) Keys() []K
Keys returns all keys in the map. This reads the signal and creates a dependency.
func (*MapSignal[K, V]) Len ¶
Len returns the number of keys in the map. This reads the signal and creates a dependency.
func (*MapSignal[K, V]) RemoveKey ¶
func (s *MapSignal[K, V]) RemoveKey(key K)
RemoveKey removes a key from the map.
func (*MapSignal[K, V]) SetKey ¶
func (s *MapSignal[K, V]) SetKey(key K, value V)
SetKey sets a key-value pair in the map.
type Memo ¶
type Memo[T any] struct { // contains filtered or unexported fields }
Memo is a cached computation that automatically tracks its dependencies. When any dependency changes, the memo is invalidated and will recompute on the next read.
Memos are lazy: they only compute their value when Get() is called. If multiple signals change before a read, the memo only recomputes once.
Memos can also be subscribed to, behaving like signals themselves. This allows building chains of derived values.
func (*Memo[T]) Get ¶
func (m *Memo[T]) Get() T
Get returns the memo's value, recomputing if necessary. Creates a dependency on this memo for the current listener.
func (*Memo[T]) ID ¶
ID returns the unique identifier for this memo. Implements the Listener interface.
func (*Memo[T]) MarkDirty ¶
func (m *Memo[T]) MarkDirty()
MarkDirty invalidates the memo and propagates to subscribers. Implements the Listener interface.
func (*Memo[T]) Metadata ¶
func (m *Memo[T]) Metadata() vruntime.PrimitiveMetadata
Metadata returns identity metadata for the primitive.
func (*Memo[T]) Peek ¶
func (m *Memo[T]) Peek() T
Peek returns the memo's value without subscribing. Still triggers recomputation if the value is invalid.
func (*Memo[T]) Unsubscribe ¶
Unsubscribe removes a listener from this memo. This is used by the runtime to remove stale subscriptions between renders.
type MemoRef ¶
MemoRef is a stable, structured description of a memo instance used for diagnostics. Fields may be empty when metadata is unavailable.
type MetricsSink ¶
type MetricsSink interface {
RecordSignalWriteViolation(operation, reason string)
RecordSessionActive(delta int)
RecordSessionDetached(delta int)
RecordResumeSuccess()
RecordResumeFailure(reason string)
RecordPatchBytes(route string, bytes int)
RecordPatchMismatch(reason string)
RecordResourceDuration(resource string, ms int64)
RecordResourceError(resource string)
RecordActionDuration(action string, ms int64)
RecordActionError(action string)
RecordSchemaMismatch(reason string)
RecordPersistWriteRejected(reason, stableID string)
RecordPersistBytes(stableID string, bytes int64)
RecordSessionPersistBytes(sessionID string, bytes int64)
RecordColdDeployAck(source string)
}
MetricsSink is the interface used by the runtime to record observability metrics. Implementations should be safe for concurrent use.
func MetricsFromContext ¶
func MetricsFromContext(ctx Ctx) MetricsSink
MetricsFromContext returns a metrics sink if available, otherwise a no-op sink.
type ModifiedHandler ¶
type ModifiedHandler struct {
// The wrapped handler function
Handler any
// Client-side modifiers
PreventDefault bool // Prevent default browser behavior
StopPropagation bool // Stop event bubbling
Self bool // Only fire if target is the exact element
Once bool // Remove handler after first trigger
Passive bool // Passive listener (cannot preventDefault)
Capture bool // Fire during capture phase
// Timing modifiers (client-side implementation)
Debounce time.Duration // Debounce delay
Throttle time.Duration // Throttle interval
// Key filtering (server-side implementation)
KeyFilter string // Single key filter (for Hotkey)
KeysFilter []string // Multiple keys filter (for Keys)
KeyModifiers KeyMod // Required modifiers (for KeyWithModifiers)
}
ModifiedHandler wraps a handler with modifier flags. The runtime recognizes this wrapper and applies the appropriate behavior: - Client-side: PreventDefault, StopPropagation, Self, Passive, Capture, Once (removal from DOM) - Server-side: Once (handler removal), key filtering, Debounce/Throttle timing
func Capture ¶
func Capture(handler any) ModifiedHandler
Capture wraps a handler to fire during the capture phase. Per spec section 3.9.3, lines 1334-1337.
Note: Due to Vango's event delegation architecture (all events are captured at the document level), per-element capture vs bubble phase control has limitations. Some events (focus, blur, scroll, mouseenter, mouseleave) are always captured, while others (click, input, keydown) bubble. This flag is available for documentation and potential future use.
Example:
OnClick(vango.Capture(func() {
// Fires during capture phase
}))
func Debounce ¶
func Debounce(duration time.Duration, handler any) ModifiedHandler
Debounce wraps a handler with debounce behavior. The handler will only be called after the specified duration has passed since the last event. Per spec section 3.9.3, lines 1339-1342.
Example:
OnInput(vango.Debounce(300*time.Millisecond, func(value string) {
search(value)
}))
func Hotkey ¶
func Hotkey(key string, handler any) ModifiedHandler
Hotkey wraps a handler to only fire on a specific key. Per spec section 3.9.3, lines 1349-1352.
Example:
OnKeyDown(vango.Hotkey("Enter", func() {
submit()
}))
OnKeyDown(vango.Hotkey(vango.KeyEscape, func() {
closeModal()
}))
func KeyWithModifiers ¶
func KeyWithModifiers(key string, mods KeyMod, handler any) ModifiedHandler
KeyWithModifiers wraps a handler to fire on a key with specific modifiers. Per spec section 3.9.3, lines 1358-1364.
Example:
OnKeyDown(vango.KeyWithModifiers("s", vango.Ctrl, func() {
save() // Ctrl+S
}))
OnKeyDown(vango.KeyWithModifiers("s", vango.Ctrl|vango.Shift, func() {
saveAs() // Ctrl+Shift+S
}))
func Keys ¶
func Keys(keys []string, handler any) ModifiedHandler
Keys wraps a handler to fire on any of the specified keys. Per spec section 3.9.3, lines 1354-1356.
Example:
OnKeyDown(vango.Keys([]string{"Enter", "NumpadEnter"}, func() {
submit()
}))
func Once ¶
func Once(handler any) ModifiedHandler
Once wraps a handler to remove it after the first trigger. Per spec section 3.9.3, lines 1324-1327.
Example:
OnClick(vango.Once(func() {
// Only fires once
}))
func Passive ¶
func Passive(handler any) ModifiedHandler
Passive wraps a handler as a passive listener for scroll performance. Passive handlers cannot call preventDefault. Per spec section 3.9.3, lines 1329-1332.
Example:
OnScroll(vango.Passive(func(e vango.ScrollEvent) {
// Cannot call preventDefault
}))
func PreventDefault ¶
func PreventDefault(handler any) ModifiedHandler
PreventDefault wraps a handler to prevent the default browser behavior. Per spec section 3.9.3, lines 1304-1307.
Example:
OnClick(vango.PreventDefault(func() {
// Click handled, default prevented
}))
func Self ¶
func Self(handler any) ModifiedHandler
Self wraps a handler to only fire if the event target is the exact element. Per spec section 3.9.3, lines 1319-1322.
Example:
OnClick(vango.Self(func() {
// Only fires if clicked element is this exact element
}))
func StopPropagation ¶
func StopPropagation(handler any) ModifiedHandler
StopPropagation wraps a handler to stop event bubbling. Per spec section 3.9.3, lines 1309-1312.
Example:
OnClick(vango.StopPropagation(func() {
// Click won't bubble up
}))
func Throttle ¶
func Throttle(duration time.Duration, handler any) ModifiedHandler
Throttle wraps a handler with throttle behavior. The handler will be called at most once per specified duration. Per spec section 3.9.3, lines 1344-1347.
Example:
OnMouseMove(vango.Throttle(100*time.Millisecond, func(e vango.MouseEvent) {
updatePosition(e.ClientX, e.ClientY)
}))
func (ModifiedHandler) Unwrap ¶
func (m ModifiedHandler) Unwrap() any
Unwrap returns the innermost handler, unwrapping any nested ModifiedHandlers.
type MouseEvent ¶
type MouseEvent struct {
// Position relative to viewport
ClientX int
ClientY int
// Position relative to document
PageX int
PageY int
// Position relative to target element
OffsetX int
OffsetY int
// Button that triggered the event (0=left, 1=middle, 2=right)
Button int
// Bitmask of currently pressed buttons
Buttons int
// Modifier keys
CtrlKey bool
ShiftKey bool
AltKey bool
MetaKey bool
}
MouseEvent represents a mouse event with position and modifiers. Per spec section 3.9.3, lines 1059-1075.
type NavigateEvent ¶
NavigateEvent represents a navigation request event.
type NoProps ¶
type NoProps struct{}
NoProps is the canonical empty-props type for components that don't need props. Use this instead of struct{} or a custom empty struct.
type NoopMetricsSink ¶
type NoopMetricsSink struct{}
NoopMetricsSink is a no-op implementation for optional metrics wiring.
func (NoopMetricsSink) RecordActionDuration ¶
func (NoopMetricsSink) RecordActionDuration(string, int64)
func (NoopMetricsSink) RecordActionError ¶
func (NoopMetricsSink) RecordActionError(string)
func (NoopMetricsSink) RecordColdDeployAck ¶
func (NoopMetricsSink) RecordColdDeployAck(string)
func (NoopMetricsSink) RecordPatchBytes ¶
func (NoopMetricsSink) RecordPatchBytes(string, int)
func (NoopMetricsSink) RecordPatchMismatch ¶
func (NoopMetricsSink) RecordPatchMismatch(string)
func (NoopMetricsSink) RecordPersistBytes ¶
func (NoopMetricsSink) RecordPersistBytes(string, int64)
func (NoopMetricsSink) RecordPersistWriteRejected ¶
func (NoopMetricsSink) RecordPersistWriteRejected(string, string)
func (NoopMetricsSink) RecordResourceDuration ¶
func (NoopMetricsSink) RecordResourceDuration(string, int64)
func (NoopMetricsSink) RecordResourceError ¶
func (NoopMetricsSink) RecordResourceError(string)
func (NoopMetricsSink) RecordResumeFailure ¶
func (NoopMetricsSink) RecordResumeFailure(string)
func (NoopMetricsSink) RecordResumeSuccess ¶
func (NoopMetricsSink) RecordResumeSuccess()
func (NoopMetricsSink) RecordSchemaMismatch ¶
func (NoopMetricsSink) RecordSchemaMismatch(string)
func (NoopMetricsSink) RecordSessionActive ¶
func (NoopMetricsSink) RecordSessionActive(int)
func (NoopMetricsSink) RecordSessionDetached ¶
func (NoopMetricsSink) RecordSessionDetached(int)
func (NoopMetricsSink) RecordSessionPersistBytes ¶
func (NoopMetricsSink) RecordSessionPersistBytes(string, int64)
func (NoopMetricsSink) RecordSignalWriteViolation ¶
func (NoopMetricsSink) RecordSignalWriteViolation(string, string)
type ObservabilityConfig ¶
type ObservabilityConfig struct {
// LogMutations enables Action/Resource intent/outcome logging.
LogMutations bool
// LogTransactions enables TxNamed transaction boundary logging.
// When enabled, TxNamed emits "vango.tx.start" and "vango.tx.end" structured logs.
//
// Default: false.
LogTransactions bool
// LogTransactionsIncludeInternal includes internal framework TxNamed calls like:
// - Action:*
// - Interval:*
// - Subscribe:*
// - GoLatest:*
// - Timeout:*
//
// Default: false.
LogTransactionsIncludeInternal bool
// LogTransactionsLevel controls the log level used for tx start/end events.
// Supported values:
// - "debug" (default)
// - "info"
LogTransactionsLevel string
// LogTransactionsMaxDepth limits TxNamed nesting depth that will be logged.
// Depth is 0 for the outermost TxNamed, 1 for nested, etc.
//
// Default: 6.
LogTransactionsMaxDepth int
// LogTransactionsMaxNameBytes truncates tx names to this many bytes (UTF-8 safe).
//
// Default: 120.
LogTransactionsMaxNameBytes int
// LogTransactionsAllowedCategories optionally restricts logging to specific categories.
// Category is the substring before the first ":" in the tx name, or the whole name if no ":" exists.
//
// If empty/nil: all categories allowed (subject to internal filtering).
LogTransactionsAllowedCategories []string
// TraceTransactionsIncludeName controls whether tx.name is included in trace events.
// By default, trace events emit only tx.category to avoid high-cardinality attributes.
//
// Default: false.
TraceTransactionsIncludeName bool
}
ObservabilityConfig controls optional observability features. All fields are opt-in and default to false.
type OnChangeRegistration ¶
type OnChangeRegistration[K comparable] struct { // contains filtered or unexported fields }
OnChangeRegistration represents a registered OnChange callback.
func (*OnChangeRegistration[K]) Metadata ¶
func (r *OnChangeRegistration[K]) Metadata() vruntime.PrimitiveMetadata
Metadata returns identity metadata for the primitive.
type OnMountRegistration ¶
type OnMountRegistration struct {
// contains filtered or unexported fields
}
OnMountRegistration represents a registered OnMount callback.
func (*OnMountRegistration) Metadata ¶
func (r *OnMountRegistration) Metadata() vruntime.PrimitiveMetadata
Metadata returns identity metadata for the primitive.
type Owner ¶
type Owner struct {
// contains filtered or unexported fields
}
Owner represents a component scope that owns reactive primitives. When an Owner is disposed, all signals, memos, effects, and child owners it contains are also disposed. This ensures proper cleanup and prevents memory leaks.
Owners form a hierarchy: each component creates an Owner that is a child of its parent component's Owner. This mirrors the component tree structure.
func NewOwner ¶
NewOwner creates a new Owner with the given parent. The new Owner is automatically registered as a child of the parent. If parent is nil, creates a root Owner.
func (*Owner) Dispose ¶
func (o *Owner) Dispose()
Dispose disposes this Owner and all its children, effects, and cleanups. Children are disposed in reverse order (last created first). After disposal, the Owner cannot be used.
func (*Owner) EndRender ¶
func (o *Owner) EndRender()
EndRender is called at the end of a component render. In debug mode, it validates that all expected hooks were called.
func (*Owner) GetValueLocal ¶
GetValueLocal retrieves a value from this Owner only, without checking parents. This is used by context Providers to check if they have already stored a contextValue in their own scope (vs. inheriting from an ancestor).
func (*Owner) HasPendingEffects ¶
HasPendingEffects returns true if this owner or any child has pending effects.
func (*Owner) IsDisposed ¶
IsDisposed returns true if this Owner has been disposed.
func (*Owner) MemoryUsage ¶
MemoryUsage estimates the memory usage of this Owner and its children.
func (*Owner) OnCleanup ¶
func (o *Owner) OnCleanup(fn func())
OnCleanup registers a cleanup function to run when this Owner is disposed.
func (*Owner) RunPendingEffects ¶
func (o *Owner) RunPendingEffects(budget StormBudgetChecker)
RunPendingEffects executes all pending effects. This is called after the render phase to run scheduled effects. The server runtime calls this after event handlers execute.
The budget parameter is optional (can be nil). When provided, effects are checked against the per-tick effect budget before running. Effects that exceed the budget are re-scheduled for the next tick.
func (*Owner) SetHookSlot ¶
SetHookSlot stores a value in the current hook slot. Must be called after UseHookSlot returns nil (first render).
func (*Owner) StartRender ¶
func (o *Owner) StartRender()
StartRender is called at the beginning of a component render. It resets the hook slot index for stable identity, and in debug mode, also resets the hook order validation index.
func (*Owner) TrackHook ¶
TrackHook records a hook call during render for order validation. In debug mode, it validates that hooks are called in the same order on every render. Violations cause a panic with a descriptive error.
func (*Owner) UseHookSlot ¶
UseHookSlot returns the stored value for the current hook slot, or stores and returns the initial value on first render. This provides stable identity for hooks (like URLParam, Resource) across renders.
Usage pattern:
func SomeHook[T any]() *T {
slot := owner.UseHookSlot(nil)
if slot != nil {
return slot.(*T) // Subsequent render: return stored instance
}
instance := &T{...} // First render: create new instance
owner.SetHookSlot(instance)
return instance
}
type PagedResponse ¶
type PagedResponse[T any] struct { Items []T `json:"items"` Page int `json:"page"` PerPage int `json:"per_page"` Total int `json:"total"` TotalPages int `json:"total_pages"` }
PagedResponse is a convenience type for paginated list responses.
type PersistBannerState ¶
type PersistBannerState struct {
// contains filtered or unexported fields
}
PersistBannerState tracks the banner state per session.
type PersistBudgetError ¶
type PersistBudgetError struct {
Kind BudgetKind
PrimitiveID string
DebugName string
RequestedBytes int64
LimitBytes int64
CurrentSessionBytes int64
IncidentCode string
}
PersistBudgetError is returned when a persisted write exceeds budget limits.
func (*PersistBudgetError) Error ¶
func (e *PersistBudgetError) Error() string
func (*PersistBudgetError) Is ¶
func (e *PersistBudgetError) Is(target error) bool
Is implements errors.Is support.
type PersistedSignalStore ¶
type PersistedSignalStore struct {
// contains filtered or unexported fields
}
PersistedSignalStore manages persisted signals for a session.
func NewPersistedSignalStore ¶
func NewPersistedSignalStore() *PersistedSignalStore
NewPersistedSignalStore creates a new persisted signal store.
func (*PersistedSignalStore) ClearDirty ¶
func (ps *PersistedSignalStore) ClearDirty()
ClearDirty marks all signals as clean.
func (*PersistedSignalStore) DirtySignals ¶
func (ps *PersistedSignalStore) DirtySignals() []string
DirtySignals returns the set of signals that need saving.
func (*PersistedSignalStore) GetOrCreateSignal ¶
func (ps *PersistedSignalStore) GetOrCreateSignal( stableID string, fingerprint codec.Fingerprint, initializer func() any, decode func([]byte) (any, error), createSignal func(any) any, ) (any, error)
GetOrCreate retrieves or creates a persisted signal.
func (*PersistedSignalStore) HasDirty ¶
func (ps *PersistedSignalStore) HasDirty() bool
HasDirty reports whether any persisted signals are marked dirty.
func (*PersistedSignalStore) Restore ¶
func (ps *PersistedSignalStore) Restore(data map[string][]byte)
Restore stores encoded persisted signals without decoding.
type PrefetchModeChecker ¶
type PrefetchModeChecker interface {
// Mode returns the current render mode.
// 0 = normal, 1 = prefetch
Mode() int
}
PrefetchModeChecker is implemented by contexts that support prefetch mode. Used by primitives to check if side effects should be suppressed.
type PrimitiveRegistration ¶
type PrimitiveRegistration struct {
AnchorKey string
StableID string
DebugName string
Kind string
Class string
Persisted bool
Primitive any
}
PrimitiveRegistration captures identity metadata for session inspection.
type PropsCell ¶
type PropsCell[P any] interface { // Get returns the current props value and creates a reactive dependency. Get() P // Peek returns the current props value without creating a dependency. Peek() P }
PropsCell is a read-only reactive cell containing component props. Get() returns the current value with dependency tracking (added in Phase 2). Peek() returns the value without tracking.
type ResizeEvent ¶
ResizeEvent represents a resize event. Per spec section 3.9.3, line 1291.
type Resource ¶
type Resource[T any] struct { // contains filtered or unexported fields }
Resource manages asynchronous data fetching and state.
func SetupResource ¶
func SetupResource[P any, T any]( s *SetupCtx[P], load func(ctx context.Context) (T, error), opts ...ResourceOption, ) *Resource[T]
SetupResource creates a runtime-only resource during Setup.
func SetupResourceKeyed ¶
func SetupResourceKeyed[P any, K comparable, T any]( s *SetupCtx[P], key func() K, load func(ctx context.Context, k K) (T, error), opts ...ResourceOption, ) *Resource[T]
SetupResourceKeyed creates a keyed resource during Setup.
func (*Resource[T]) Fetch ¶
func (r *Resource[T]) Fetch()
Fetch triggers a data fetch. It respects StaleTime if data is already ready. To force a fetch, use Refetch().
func (*Resource[T]) Invalidate ¶
func (r *Resource[T]) Invalidate()
Invalidate marks the current data as stale.
func (*Resource[T]) Metadata ¶
func (r *Resource[T]) Metadata() vruntime.PrimitiveMetadata
Metadata returns identity metadata for the primitive.
func (*Resource[T]) Mutate ¶
func (r *Resource[T]) Mutate(fn func(T) T)
Mutate optimistically updates the local data.
func (*Resource[T]) OnSuccess ¶
OnSuccess registers a callback to be called when data is successfully loaded.
func (*Resource[T]) Refetch ¶
func (r *Resource[T]) Refetch()
Refetch forces a data fetch, bypassing cache. All signal writes are dispatched via ctx.Dispatch to ensure thread safety.
func (*Resource[T]) ResourceCacheSize ¶
ResourceCacheSize configures the maximum number of cached key entries for keyed resources. This is used only by ResourceKeyed; non-keyed resources ignore it.
func (*Resource[T]) RetryOnError ¶
RetryOnError sets the number of retries and delay between them.
type ResourceOption ¶
type ResourceOption interface {
// contains filtered or unexported methods
}
ResourceOption configures a Resource created by SetupCtx.
func OnResourceError ¶
func OnResourceError(fn func(error)) ResourceOption
OnResourceError registers an error callback for resource loads.
func OnResourceSuccess ¶
func OnResourceSuccess(fn func(any)) ResourceOption
OnResourceSuccess registers a success callback for resource loads.
func ResourceCacheSize ¶
func ResourceCacheSize(n int) ResourceOption
ResourceCacheSize configures the maximum number of cached key entries for ResourceKeyed. This enables fast reuse when switching between a bounded set of keys.
Note: only keyed resources use this option; non-keyed resources ignore it.
func RetryOnError ¶
func RetryOnError(count int, delay time.Duration) ResourceOption
RetryOnError configures retry count and delay.
func StaleTime ¶
func StaleTime(d time.Duration) ResourceOption
StaleTime sets the duration before data is considered stale.
type Response ¶
type Response[T any] struct { // Data is the response payload. Data T `json:"data,omitempty"` // Meta contains optional metadata (pagination, counts, etc.) Meta map[string]any `json:"meta,omitempty"` // StatusCode is the HTTP status code for this response. // Not included in JSON output. StatusCode int `json:"-"` }
Response wraps an API response with optional metadata. It provides a standard structure for JSON API responses.
Example usage in API handlers:
func GET(ctx vango.Ctx) (*vango.Response[[]Project], error) {
projects, err := db.Projects.All()
if err != nil {
return nil, vango.InternalError(err)
}
return vango.OK(projects), nil
}
func POST(ctx vango.Ctx, input CreateProjectInput) (*vango.Response[*Project], error) {
project, err := db.Projects.Create(input)
if err != nil {
return nil, vango.BadRequest(err)
}
return vango.Created(project), nil
}
func NoContent ¶
NoContent creates a 204 No Content response. Typically used for successful DELETE operations.
func Paginated ¶
func Paginated[T any](items []T, page, perPage, total int) *Response[PagedResponse[T]]
Paginated creates a paginated response.
func (*Response[T]) WithPagination ¶
WithPagination adds pagination metadata to the response.
type ScrollEvent ¶
type ScrollEvent struct {
// Scroll position from top
ScrollTop int
// Scroll position from left
ScrollLeft int
}
ScrollEvent represents a scroll event. Per spec section 3.9.3, lines 1269-1271.
type SessionKey ¶
type SessionKey[T any] struct { // contains filtered or unexported fields }
SessionKey is a typed, schema-safe session key. SessionKeys declared at package scope participate in the schema hash.
func NewSessionKey ¶
func NewSessionKey[T any](name string, opts ...SessionKeyOption[T]) *SessionKey[T]
NewSessionKey creates a typed session key. The name must be a string literal for static discoverability by tooling.
func (*SessionKey[T]) CodecFingerprint ¶
func (sk *SessionKey[T]) CodecFingerprint() codec.Fingerprint
CodecFingerprint returns the schema fingerprint for this key.
func (*SessionKey[T]) DefaultValue ¶
func (sk *SessionKey[T]) DefaultValue() T
DefaultValue returns the default value (or zero value if no default).
func (*SessionKey[T]) Delete ¶
func (sk *SessionKey[T]) Delete(ctx Ctx)
Delete removes the value from the session.
func (*SessionKey[T]) Get ¶
func (sk *SessionKey[T]) Get(ctx Ctx) T
Get retrieves the value from the session context. Returns the default value (or zero value) if the key is absent.
func (*SessionKey[T]) HasDefault ¶
func (sk *SessionKey[T]) HasDefault() bool
HasDefault reports whether a default value was provided.
func (*SessionKey[T]) Peek ¶
func (sk *SessionKey[T]) Peek(ctx Ctx) (T, bool)
Peek retrieves the value without tracking.
func (*SessionKey[T]) Set ¶
func (sk *SessionKey[T]) Set(ctx Ctx, value T) error
Set stores the value in the session context.
func (*SessionKey[T]) StableID ¶
func (sk *SessionKey[T]) StableID() string
StableID returns the stable ID (empty if not bound by generated bindings).
type SessionKeyInfo ¶
type SessionKeyInfo struct {
Name string
StableID string
Fingerprint codec.Fingerprint
HasDefault bool
DefaultValue any
Decode func([]byte) (any, error)
}
SessionKeyInfo contains metadata for a registered session key.
func GetSessionKeyByStableID ¶
func GetSessionKeyByStableID(stableID string) (SessionKeyInfo, bool)
GetSessionKeyByStableID returns a registered session key by stable ID.
type SessionKeyOption ¶
type SessionKeyOption[T any] func(*SessionKey[T])
SessionKeyOption configures a SessionKey.
func Default ¶
func Default[T any](v T) SessionKeyOption[T]
Default sets the default value for when the key is absent. Without Default(), absence returns the zero value of T.
type SessionSignalStore ¶
type SessionSignalStore interface {
// GetOrCreateSignal retrieves an existing signal by stable ID, or creates
// a new one using the provided factory function if it doesn't exist.
GetOrCreateSignal(stableID string, createFn func() any) any
}
SessionSignalStore is the interface for session-scoped shared signal storage. The store maps stable IDs to per-session signal instances.
type SetupComponent ¶
type SetupComponent[P any] struct { // contains filtered or unexported fields }
SetupComponent is a component created by vango.Setup. It carries the setup callback and current props for runtime integration.
func (*SetupComponent[P]) ApplyProps ¶
func (sc *SetupComponent[P]) ApplyProps(state *SetupState) bool
ApplyProps updates the setup state with the current props. Returns true if the props changed.
func (*SetupComponent[P]) Invoker ¶
func (sc *SetupComponent[P]) Invoker() SetupComponentInvoker
Invoker returns the type-erased setup invocation function.
func (*SetupComponent[P]) IsSetupComponent ¶
func (sc *SetupComponent[P]) IsSetupComponent() bool
IsSetupComponent identifies this as a Setup-based component.
func (*SetupComponent[P]) Props ¶
func (sc *SetupComponent[P]) Props() any
Props returns the current props as an untyped value.
func (*SetupComponent[P]) Render ¶
func (sc *SetupComponent[P]) Render() *vdom.VNode
Render implements vdom.Component. This one-shot path is used for SSR/diff/navigation where no component instance exists.
type SetupComponentDetector ¶
type SetupComponentDetector interface {
IsSetupComponent() bool
Props() any
ApplyProps(state *SetupState) bool
Invoker() SetupComponentInvoker
}
SetupComponentDetector is implemented by Setup components for runtime detection.
type SetupComponentInvoker ¶
type SetupComponentInvoker func(owner *Owner, state *SetupState, props any, ctx Ctx) RenderFn
SetupComponentInvoker is the type-erased invocation function for Setup callbacks.
type SetupCtx ¶
type SetupCtx[P any] struct { // contains filtered or unexported fields }
SetupCtx provides access to props and context during setup. Typed reactive primitives are provided via package-level helpers in package setup.
func (SetupCtx[P]) OnPersistError ¶
func (s SetupCtx[P]) OnPersistError(fn func(*PersistBudgetError))
OnPersistError registers a session-scoped persistence error handler.
type SetupState ¶
type SetupState struct {
// contains filtered or unexported fields
}
SetupState holds runtime state for a Setup-based component instance.
func NewSetupState ¶
func NewSetupState() *SetupState
NewSetupState creates a new SetupState for component instances.
func (*SetupState) AddOnMount ¶
func (s *SetupState) AddOnMount(reg *OnMountRegistration)
func (*SetupState) AddRegistration ¶
func (s *SetupState) AddRegistration(reg PrimitiveRegistration)
AddRegistration stores a primitive registration for session inspection.
func (*SetupState) Dispose ¶
func (s *SetupState) Dispose()
Dispose runs OnMount cleanups and releases references.
func (*SetupState) GetRenderFn ¶
func (s *SetupState) GetRenderFn() RenderFn
func (*SetupState) IsOnMountPending ¶
func (s *SetupState) IsOnMountPending() bool
func (*SetupState) IsSetupComplete ¶
func (s *SetupState) IsSetupComplete() bool
func (*SetupState) MarkSetupComplete ¶
func (s *SetupState) MarkSetupComplete()
func (*SetupState) Registrations ¶
func (s *SetupState) Registrations() []PrimitiveRegistration
Registrations returns a copy of the stored primitive registrations.
func (*SetupState) RunOnMountHooks ¶
func (s *SetupState) RunOnMountHooks()
RunOnMountHooks executes all OnMount hooks registered during setup.
func (*SetupState) SetOnMountPending ¶
func (s *SetupState) SetOnMountPending(pending bool)
func (*SetupState) SetRenderFn ¶
func (s *SetupState) SetRenderFn(fn RenderFn)
func (*SetupState) UpdateProps ¶
func (s *SetupState) UpdateProps(newProps any) bool
UpdateProps updates the props cell and notifies dependents. Returns true if props changed.
type Signal ¶
type Signal[T any] struct { // contains filtered or unexported fields }
Signal is a reactive value container. Reading a Signal's value during a tracked context (component render, memo computation, or effect execution) automatically subscribes the current listener to receive notifications when the value changes.
func NewSignalForTest ¶
NewSignalForTest creates a signal for tests outside the vango package. Prefer setup.Signal in production code.
func SetupGlobalSignal ¶
SetupGlobalSignal creates a global signal during Setup.
func SetupSharedSignal ¶
SetupSharedSignal creates a session-scoped signal during Setup.
func SetupSignal ¶
SetupSignal creates a local signal during Setup.
func (*Signal[T]) Add ¶
Add adds n to the value. The parameter n must be the same numeric type as the signal's value. Panics if the signal's type is not numeric or if n is the wrong type.
func (*Signal[T]) Append ¶
Append appends a suffix to a string value. Panics if the signal's type is not string.
func (*Signal[T]) AppendItem ¶
AppendItem appends an item to a slice value. The item must be assignable to the slice's element type. Panics if the signal's type is not a slice.
func (*Signal[T]) Clear ¶
func (s *Signal[T]) Clear()
Clear sets the value to its empty state. Works for string (empty string), slice (empty slice), and map (empty map). Panics if the signal's type is not one of these.
func (*Signal[T]) Dec ¶
func (s *Signal[T]) Dec()
Dec decrements the value by 1. Panics if the signal's type is not numeric.
func (*Signal[T]) Div ¶
Div divides the value by n. The parameter n must be the same numeric type as the signal's value. Panics if the signal's type is not numeric or if n is the wrong type. Note: Integer division truncates toward zero.
func (*Signal[T]) Filter ¶
Filter keeps only items that satisfy the predicate. Panics if the signal's type is not a slice.
func (*Signal[T]) Get ¶
func (s *Signal[T]) Get() T
Get returns the current value and subscribes the current listener. If called during a tracked context (component render, memo computation, or effect execution), the current listener will be notified when this signal's value changes.
func (*Signal[T]) GetAny ¶
GetAny returns the current value as an interface{}. This is used for serialization without knowing the concrete type.
func (*Signal[T]) HasKey ¶
HasKey returns true if the key exists in the map. Panics if the signal's type is not a map.
func (*Signal[T]) Inc ¶
func (s *Signal[T]) Inc()
Inc increments the value by 1. Panics if the signal's type is not numeric.
func (*Signal[T]) InsertAt ¶
InsertAt inserts an item at the given index. If index is out of bounds, the item is appended (if index >= len) or prepended (if index < 0). Panics if the signal's type is not a slice.
func (*Signal[T]) Len ¶
Len returns the length of the value. Works for string, slice, and map types. Panics if the signal's type is not one of these. This reads the signal and creates a dependency.
func (*Signal[T]) Metadata ¶
func (s *Signal[T]) Metadata() vruntime.PrimitiveMetadata
Metadata returns identity metadata for the primitive.
func (*Signal[T]) Mul ¶
Mul multiplies the value by n. The parameter n must be the same numeric type as the signal's value. Panics if the signal's type is not numeric or if n is the wrong type.
func (*Signal[T]) Peek ¶
func (s *Signal[T]) Peek() T
Peek returns the current value without subscribing. This is useful when you need to read a value without creating a dependency.
func (*Signal[T]) Prepend ¶
Prepend prepends a prefix to a string value. Panics if the signal's type is not string.
func (*Signal[T]) PrependItem ¶
PrependItem prepends an item to a slice value. The item must be assignable to the slice's element type. Panics if the signal's type is not a slice.
func (*Signal[T]) RemoveAt ¶
RemoveAt removes the item at the given index. Does nothing if index is out of bounds. Panics if the signal's type is not a slice.
func (*Signal[T]) RemoveFirst ¶
func (s *Signal[T]) RemoveFirst()
RemoveFirst removes the first item from the slice. Does nothing if the slice is empty. Panics if the signal's type is not a slice.
func (*Signal[T]) RemoveKey ¶
RemoveKey removes a key from a map. Does nothing if the key doesn't exist. Panics if the signal's type is not a map.
func (*Signal[T]) RemoveLast ¶
func (s *Signal[T]) RemoveLast()
RemoveLast removes the last item from the slice. Does nothing if the slice is empty. Panics if the signal's type is not a slice.
func (*Signal[T]) RemoveWhere ¶
RemoveWhere removes all items that satisfy the predicate. The predicate receives each item as any and returns true to remove it. Panics if the signal's type is not a slice.
func (*Signal[T]) Set ¶
func (s *Signal[T]) Set(value T)
Set updates the signal's value and notifies subscribers if the value changed. Uses the signal's equality function to determine if the value changed.
func (*Signal[T]) SetAny ¶
SetAny sets the value from an interface{}. Returns an error if the type doesn't match. This is used for deserialization without knowing the concrete type.
func (*Signal[T]) SetAt ¶
SetAt sets the item at the given index. Does nothing if index is out of bounds. Panics if the signal's type is not a slice.
func (*Signal[T]) SetFalse ¶
func (s *Signal[T]) SetFalse()
SetFalse sets the value to false. Panics if the signal's type is not bool.
func (*Signal[T]) SetKey ¶
SetKey sets a key-value pair in a map. The key and value must be assignable to the map's key and value types. Panics if the signal's type is not a map.
func (*Signal[T]) SetTrue ¶
func (s *Signal[T]) SetTrue()
SetTrue sets the value to true. Panics if the signal's type is not bool.
func (*Signal[T]) Sub ¶
Sub subtracts n from the value. The parameter n must be the same numeric type as the signal's value. Panics if the signal's type is not numeric or if n is the wrong type.
func (*Signal[T]) Toggle ¶
func (s *Signal[T]) Toggle()
Toggle inverts a boolean value. Panics if the signal's type is not bool.
func (*Signal[T]) Unsubscribe ¶
Unsubscribe removes a listener from this signal. This is used by the runtime to remove stale subscriptions between renders.
func (*Signal[T]) Update ¶
func (s *Signal[T]) Update(fn func(T) T)
Update atomically reads and updates the signal's value. The function receives the current value and returns the new value.
func (*Signal[T]) UpdateAt ¶
UpdateAt updates the item at the given index using the provided function. Does nothing if index is out of bounds. Panics if the signal's type is not a slice.
func (*Signal[T]) UpdateKey ¶
UpdateKey updates a key's value using the provided function. If the key doesn't exist, the function receives nil/zero value. Panics if the signal's type is not a map.
func (*Signal[T]) UpdateWhere ¶
UpdateWhere updates all items that satisfy the predicate using the provided function. Panics if the signal's type is not a slice.
func (*Signal[T]) WithEquals ¶
WithEquals returns the signal configured with a custom equality function. This is useful for custom types where reflect.DeepEqual is too expensive or has incorrect semantics.
type SimpleSessionSignalStore ¶
type SimpleSessionSignalStore struct {
// contains filtered or unexported fields
}
SimpleSessionSignalStore is a basic implementation of SessionSignalStore using sync.Map for concurrent access.
func NewSimpleSessionSignalStore ¶
func NewSimpleSessionSignalStore() *SimpleSessionSignalStore
NewSimpleSessionSignalStore creates a new simple session signal store.
func (*SimpleSessionSignalStore) GetOrCreateSignal ¶
func (s *SimpleSessionSignalStore) GetOrCreateSignal(stableID string, createFn func() any) any
GetOrCreateSignal retrieves an existing signal or creates a new one.
type SliceSignal
deprecated
SliceSignal wraps Signal[[]T] with convenience methods for slice operations.
Deprecated: Use setup.Signal inside vango.Setup. Signal[[]T] now has AppendItem(), PrependItem(), InsertAt(), RemoveAt(), SetAt(), UpdateAt(), RemoveWhere(), UpdateWhere(), Filter(), Clear(), and Len() methods directly available.
Note: SliceSignal[T] provides type-safe methods (e.g., Append(item T)) while the Signal[T] methods use any (e.g., AppendItem(item any)). Use SliceSignal[T] if you prefer compile-time type safety over the unified API.
// Old:
items := vango.NewSliceSignal([]Item{})
items.Append(newItem)
// New:
items := setup.Signal(&s, []Item{})
items.AppendItem(newItem) // Note: uses 'any' parameter
func NewSliceSignal
deprecated
func NewSliceSignal[T any](initial []T) *SliceSignal[T]
NewSliceSignal creates a new SliceSignal with the given initial value. If initial is nil, creates an empty slice.
Deprecated: Use setup.Signal inside vango.Setup. Signal[[]T] now has slice convenience methods directly available. SliceSignal[T] is retained for type-safe slice operations if preferred.
func (*SliceSignal[T]) Append ¶
func (s *SliceSignal[T]) Append(item T)
Append adds an item to the end of the slice.
func (*SliceSignal[T]) AppendAll ¶
func (s *SliceSignal[T]) AppendAll(items ...T)
AppendAll adds multiple items to the end of the slice.
func (*SliceSignal[T]) Clear ¶
func (s *SliceSignal[T]) Clear()
Clear removes all items from the slice.
func (*SliceSignal[T]) Filter ¶
func (s *SliceSignal[T]) Filter(predicate func(T) bool)
Filter keeps only items that satisfy the predicate.
func (*SliceSignal[T]) InsertAt ¶
func (s *SliceSignal[T]) InsertAt(index int, item T)
InsertAt inserts an item at the given index. If index is out of bounds, the item is appended (if index >= len) or prepended (if index < 0).
func (*SliceSignal[T]) Len ¶
func (s *SliceSignal[T]) Len() int
Len returns the length of the slice. This reads the signal and creates a dependency.
func (*SliceSignal[T]) Prepend ¶
func (s *SliceSignal[T]) Prepend(item T)
Prepend adds an item to the beginning of the slice.
func (*SliceSignal[T]) RemoveAt ¶
func (s *SliceSignal[T]) RemoveAt(index int)
RemoveAt removes the item at the given index. Does nothing if index is out of bounds.
func (*SliceSignal[T]) RemoveFirst ¶
func (s *SliceSignal[T]) RemoveFirst()
RemoveFirst removes and returns the first item from the slice. Does nothing if the slice is empty.
func (*SliceSignal[T]) RemoveLast ¶
func (s *SliceSignal[T]) RemoveLast()
RemoveLast removes the last item from the slice. Does nothing if the slice is empty.
func (*SliceSignal[T]) RemoveWhere ¶
func (s *SliceSignal[T]) RemoveWhere(predicate func(T) bool)
RemoveWhere removes all items that satisfy the predicate.
func (*SliceSignal[T]) SetAt ¶
func (s *SliceSignal[T]) SetAt(index int, item T)
SetAt sets the item at the given index. Does nothing if index is out of bounds.
func (*SliceSignal[T]) UpdateAt ¶
func (s *SliceSignal[T]) UpdateAt(index int, fn func(T) T)
UpdateAt updates the item at the given index using the provided function. Does nothing if index is out of bounds.
func (*SliceSignal[T]) UpdateWhere ¶
func (s *SliceSignal[T]) UpdateWhere(predicate func(T) bool, fn func(T) T)
UpdateWhere updates all items that satisfy the predicate using the provided function.
type Slot ¶
type Slot struct {
// contains filtered or unexported fields
}
Slot is an opaque, framework-owned renderable container for children. It is intended for use in props structs and layout handlers.
func (Slot) ChildrenNodes ¶
ChildrenNodes exposes Slot nodes to the VDOM integration layer. This is intended for framework use only.
type StateBudgetConfig ¶
StateBudgetConfig configures limits on persisted state size. Zero values fall back to defaults.
func ResolveStateBudget ¶
func ResolveStateBudget(cfg *StateBudgetConfig) StateBudgetConfig
ResolveStateBudget returns a StateBudgetConfig with defaults applied.
type StormBudgetChecker ¶
type StormBudgetChecker interface {
CheckResource() error
CheckAction() error
CheckGoLatest() error
CheckEffectRun() error
ResetTick()
}
StormBudgetChecker is the interface exposed to primitives for budget checking. This is implemented by Session and exposed via Ctx.
type StormBudgetConfig ¶
type StormBudgetConfig struct {
MaxResourceStartsPerSecond int
MaxActionStartsPerSecond int
MaxGoLatestStartsPerSecond int
MaxEffectRunsPerTick int
WindowDuration time.Duration
OnExceeded BudgetExceededMode
}
StormBudgetConfig holds configuration for storm budgets. This mirrors the server/config.StormBudgetConfig for use in the vango package.
type StormBudgetTracker ¶
type StormBudgetTracker struct {
// contains filtered or unexported fields
}
StormBudgetTracker tracks rate limits for effect primitives. It provides protection against amplification bugs where effects cascade into more effects, potentially causing performance issues or infinite loops.
func NewStormBudgetTracker ¶
func NewStormBudgetTracker(cfg *StormBudgetConfig) *StormBudgetTracker
NewStormBudgetTracker creates a new storm budget tracker with the given configuration.
func (*StormBudgetTracker) CheckAction ¶
func (t *StormBudgetTracker) CheckAction() error
CheckAction checks if an Action can start. Returns nil if allowed, ErrBudgetExceeded if rate limited.
func (*StormBudgetTracker) CheckEffectRun ¶
func (t *StormBudgetTracker) CheckEffectRun() error
CheckEffectRun checks if another effect can run this tick. Returns nil if allowed, ErrBudgetExceeded if limit reached.
func (*StormBudgetTracker) CheckGoLatest ¶
func (t *StormBudgetTracker) CheckGoLatest() error
CheckGoLatest checks if GoLatest work can start. Returns nil if allowed, ErrBudgetExceeded if rate limited.
func (*StormBudgetTracker) CheckResource ¶
func (t *StormBudgetTracker) CheckResource() error
CheckResource checks if a Resource fetch can start. Returns nil if allowed, ErrBudgetExceeded if rate limited.
func (*StormBudgetTracker) GetOnExceeded ¶
func (t *StormBudgetTracker) GetOnExceeded() BudgetExceededMode
GetOnExceeded returns the configured behavior when budget is exceeded.
func (*StormBudgetTracker) ResetTick ¶
func (t *StormBudgetTracker) ResetTick()
ResetTick resets the per-tick counters. Should be called at the start of each event/dispatch processing.
func (*StormBudgetTracker) Stats ¶
func (t *StormBudgetTracker) Stats() BudgetStats
type Stream ¶
type Stream[T any] interface { Subscribe(handler func(T)) (unsubscribe func()) }
Stream is an interface for event streams that support subscription. The Subscribe method returns an unsubscribe function.
type StrictEffectMode ¶
type StrictEffectMode int
StrictEffectMode controls how effect-time signal writes are handled. This helps catch bugs where effects modify signals during their synchronous body, which can cause unexpected re-renders and cascading effects.
See SPEC_ADDENDUM.md §A.3 for effect enforcement details.
const ( // StrictEffectOff disables effect-time write detection. // No warnings or errors for signal writes during effects. StrictEffectOff StrictEffectMode = iota // StrictEffectWarn logs a warning when an effect writes to a signal // without the AllowWrites() option. This is the recommended mode for // development to catch bugs without breaking existing code. StrictEffectWarn // StrictEffectPanic panics when an effect writes to a signal without // the AllowWrites() option. Use this mode to strictly enforce the rule // during testing or in strict development environments. StrictEffectPanic )
type StringSignal
deprecated
StringSignal wraps Signal[string] with convenience methods for string operations.
Deprecated: Use setup.Signal inside vango.Setup. Signal[string] now has Append(), Prepend(), Clear(), and Len() methods directly available.
// Old:
text := vango.NewStringSignal("")
text.Append("hello")
// New:
text := setup.Signal(&s, "")
text.Append("hello")
func NewStringSignal
deprecated
func NewStringSignal(initial string) *StringSignal
NewStringSignal creates a new StringSignal with the given initial value.
Deprecated: Use setup.Signal inside vango.Setup. Signal[string] now has Append(), Prepend(), Clear(), and Len() methods directly available.
func (*StringSignal) Append ¶
func (s *StringSignal) Append(suffix string)
Append adds the given string to the end.
func (*StringSignal) Clear ¶
func (s *StringSignal) Clear()
Clear sets the value to an empty string.
func (*StringSignal) IsEmpty ¶
func (s *StringSignal) IsEmpty() bool
IsEmpty returns true if the string is empty. This reads the signal and creates a dependency.
func (*StringSignal) Len ¶
func (s *StringSignal) Len() int
Len returns the length of the string. This reads the signal and creates a dependency.
func (*StringSignal) Prepend ¶
func (s *StringSignal) Prepend(prefix string)
Prepend adds the given string to the beginning.
type SubscribeOption ¶
type SubscribeOption interface {
// contains filtered or unexported methods
}
SubscribeOption is an option for configuring Subscribe.
func SubscribeTxName ¶
func SubscribeTxName(name string) SubscribeOption
SubscribeTxName sets the transaction name for observability. Messages will appear in DevTools as Subscribe:<name>.
type TimeoutOption ¶
type TimeoutOption interface {
// contains filtered or unexported methods
}
TimeoutOption is an option for configuring Timeout.
func TimeoutTxName ¶
func TimeoutTxName(name string) TimeoutOption
TimeoutTxName sets the transaction name for observability. The timeout will appear in DevTools as Timeout:<name>.
type Touch ¶
type Touch struct {
// Unique identifier for the touch point
Identifier int
// Position relative to viewport
ClientX int
ClientY int
// Position relative to document
PageX int
PageY int
}
Touch represents a single touch point. Per spec section 3.9.3, lines 1219-1225.
type TouchEvent ¶
type TouchEvent struct {
// All current touches on the screen
Touches []Touch
// Touches that started on this element
TargetTouches []Touch
// Touches that changed in this event
ChangedTouches []Touch
}
TouchEvent represents a touch event. Per spec section 3.9.3, lines 1212-1217.
type TrackingContext ¶
type TrackingContext struct {
// contains filtered or unexported fields
}
TrackingContext holds the reactive state for a goroutine. Each goroutine has its own tracking context to support concurrent component rendering and signal access.
type TransitionEvent ¶
type TransitionEvent struct {
// Name of the CSS property being transitioned
PropertyName string
// Time in seconds since the transition started
ElapsedTime float64
// Pseudo-element the transition runs on
PseudoElement string
}
TransitionEvent represents a CSS transition event. Per spec section 3.9.3, lines 1236-1239.
type TxTraceEvent ¶
type TxTraceEvent struct {
Category string
Name string
Depth int
CommitBoundary bool
Outcome string
DurationMs int64
}
TxTraceEvent is emitted to an optional trace hook stored in StdContext().
This is intentionally low-cardinality by default: - Category is recommended for trace attributes. - Name may be omitted depending on configuration.
type TxTraceHook ¶
type TxTraceHook interface {
OnTxStart(ctx context.Context, ev TxTraceEvent)
OnTxEnd(ctx context.Context, ev TxTraceEvent)
}
TxTraceHook receives TxNamed start/end events for trace integration. Implementations must be safe for concurrent use.
type TypeMismatchError ¶
TypeMismatchError is returned when SetAny receives a value of the wrong type.
func (*TypeMismatchError) Error ¶
func (e *TypeMismatchError) Error() string
type TypedPropsCell ¶
type TypedPropsCell[P any] struct { // contains filtered or unexported fields }
TypedPropsCell wraps propsCellImpl for type-safe access.
func (*TypedPropsCell[P]) Get ¶
func (t *TypedPropsCell[P]) Get() P
func (*TypedPropsCell[P]) Peek ¶
func (t *TypedPropsCell[P]) Peek() P
type WasmMessage ¶
type WasmMessage struct {
// ID is the wasm component name/module identifier (the value of data-wasm).
ID string
// HID is the unique instance address (the hydration id of the wasm boundary element).
// This allows multiple instances with the same ID to coexist on a page.
HID string
Raw json.RawMessage
}
WasmMessage represents a message sent between a WASM component and the server.
type WasmMessageHandler ¶
type WasmMessageHandler func(WasmMessage)
WasmMessageHandler handles messages emitted by client WASM components.
type WasmMessageValidator ¶
type WasmMessageValidator func(WasmMessage) error
WasmMessageValidator validates a WASM message payload. Return an error to reject the message.
func WasmSchemaValidator ¶
func WasmSchemaValidator[T any](validate func(WasmMessage, T) error) WasmMessageValidator
WasmSchemaValidator builds a WasmMessageValidator that decodes WASM message payloads into a typed schema using strict JSON rules.
The callback may be nil to run schema decoding only.
type WasmMessenger ¶
type WasmMessenger interface {
RegisterWasmHandler(id string, handler WasmMessageHandler) func()
SendWasmMessage(id string, payload any) error
SendWasmMessageToHID(hid string, payload any) error
}
WasmMessenger describes session capabilities for WASM messaging.
type WheelEvent ¶
type WheelEvent struct {
// Scroll amounts
DeltaX float64
DeltaY float64
DeltaZ float64
// Delta mode: 0=pixels, 1=lines, 2=pages
DeltaMode int
// Position relative to viewport
ClientX int
ClientY int
// Modifier keys
CtrlKey bool
ShiftKey bool
AltKey bool
MetaKey bool
}
WheelEvent represents a mouse wheel event. Per spec section 3.9.3, line 1056.
type WorkerContext ¶
type WorkerContext struct {
Kind WorkerKind
WorkerStableID string
WorkerDebugName string
WorkerAnchorKey string
// RuntimeCtx is the originating runtime context for the session, if available.
// This is used to locate the session for self-heal behavior on violations.
RuntimeCtx Ctx
}
WorkerContext carries metadata about the current framework worker. This is goroutine-local and is used to produce actionable diagnostics and to fail safe (session self-heal) on correctness violations in production.
type WorkerKind ¶
type WorkerKind string
WorkerKind identifies which framework worker context is currently executing. These run off the session loop and must never write reactive state directly.
const ( WorkerResourceLoader WorkerKind = "resource_loader" WorkerActionWork WorkerKind = "action_work" )
Source Files
¶
- action.go
- action_match.go
- action_options.go
- batch.go
- budget.go
- budget_banner.go
- config.go
- context.go
- context_api.go
- dependencies.go
- doc.go
- effect.go
- errors.go
- event_modifiers.go
- event_security.go
- event_validation_helpers.go
- events.go
- exports.go
- global_signal_blob.go
- helpers.go
- id.go
- islands.go
- keys.go
- lint_markers.go
- listener.go
- memo.go
- memo_cycle_panic.go
- metrics.go
- metrics_helpers.go
- observability.go
- owner.go
- persist_batch.go
- primitive_meta.go
- pubsub_memory.go
- pubsub_redis.go
- registrations.go
- resource.go
- resource_match.go
- resource_options.go
- response.go
- session_key.go
- session_key_registry.go
- session_loop_dispatch.go
- session_refresh_banner.go
- setup.go
- setup_component.go
- setup_ctx.go
- setup_helpers.go
- setup_props.go
- setup_slot.go
- setup_state.go
- signal.go
- signal_bool.go
- signal_global_store.go
- signal_int.go
- signal_map.go
- signal_persistence.go
- signal_shared.go
- signal_slice.go
- signal_store_keys.go
- signal_string.go
- ssr_resources.go
- storm_budget.go
- testid.go
- testing.go
- tracking.go
- transaction.go
- tx_trace_hook.go
- wasm.go