core library
Pure-Dart core of all_observer: the dependency tracker, listener
registry, batch/flush engine, typedefs, and observability primitives
(ObserverInspector, RecordingInspector), plus the untracked()
escape hatch, the ReactiveScope/ScopedObserverMixin scoped-cleanup
primitives, and the error-reporting hook — with zero import of
package:flutter. Usable from a CLI/server context, not just Flutter
apps.
This is a subset of package:all_observer/all_observer.dart:
Observable, Computed, effect(), the reactive collections, and the
Observer/ObserverValue widgets are not exported here yet — they
still depend on Flutter for ValueListenable/kDebugMode/console
logging. Import all_observer.dart for those, as before; this file
exists for tooling that wants the low-level reactive primitives
(ListenerRegistry, BatchScope, DependencyTracker) or the
observability types without pulling in Flutter at all.
Núcleo em Dart puro do all_observer: o rastreador de dependências, o
registro de listeners, o motor de batch/flush, os typedefs, e as
primitivas de observabilidade (ObserverInspector, RecordingInspector),
além da escapatória untracked(), das primitivas de limpeza escopada
ReactiveScope/ScopedObserverMixin e o gancho de relato de erros —
com zero import de package:flutter. Utilizável em um contexto de
CLI/servidor, não só em apps Flutter.
Este é um subconjunto de package:all_observer/all_observer.dart:
Observable, Computed, effect(), as coleções reativas e os widgets
Observer/ObserverValue ainda não são exportados aqui — eles ainda
dependem de Flutter para ValueListenable/kDebugMode/logging no
console. Importe all_observer.dart para isso, como antes; este arquivo
existe para ferramental que queira as primitivas reativas de baixo nível
(ListenerRegistry, BatchScope, DependencyTracker) ou os tipos de
observabilidade sem trazer Flutter junto.
Classes
- BatchScope
-
Tracks the currently active
Observable.batch()nesting depth and the set of ListenerRegistrys pending notification once the outermost batch completes. - ComputedEngineNode
-
Engine identity of a
CoreComputed, delegating engine callbacks to the owning instance (which keepsequals, memoization and inspector events). -
CoreComputed<
T> -
Pure-Dart derived-value engine: the same lazy/memoized, glitch-free
tracking behind
Computed, without any dependency onpackage:flutter— noValueListenable, nokDebugMode-gated console logging. Usable from a CLI/server context viapackage:all_observer/core.dart. - CoreErrorReporting
-
Pure-Dart hook the core uses to surface an exception it caught and
isolated (a listener/
Computed/Effectthat threw, or a detected update cycle) to whatever hosting framework/tooling is present, without the core itself depending on Flutter. -
CoreObservable<
T> -
Pure-Dart reactive value holder: the same tracking/notification engine
behind
Observable, without any dependency onpackage:flutter— noValueListenable, nokDebugMode-gated console logging. Usable from a CLI/server context viapackage:all_observer/core.dart. - DependencyTracker
- Reentrant stack-based dependency tracker.
- EffectEvent
-
Emitted every time an
Effect's body actually runs (including its initial run). - ListenerRegistry
- Holds the set of listeners attached to a single observable and notifies them safely, tolerating listeners that add/remove other listeners during notification.
- ObservableCreateEvent
-
Emitted when an Observable/
Computedis created. - ObservableDisposeEvent
-
Emitted when an Observable/
Computedis disposed. - ObservableEvent
- Base for every event ObserverInspector receives: carries the label of the observable/Computed/Effect/Observer involved and the moment it occurred.
-
ObservableStore<
T> -
Optional integration point for persisting and restoring the value of an
Observable against some external storage — implemented by a bridge
package (e.g.
all_box) that knows how to read/write/serializeT, not byall_observeritself, which stays free of any I/O, serialization, or storage dependency. - ObservableSubscription
-
A handle returned by Observable.listen representing a manual
subscription, implemented directly over ListenerRegistry — no
Streaminvolved. - ObservableUpdateEvent
-
Emitted when an Observable/
Computednotifies a value change. - ObserverConfig
- Global, mutable configuration for the package's debug behavior.
- ObserverEngine
-
The
all_observerpreset of the public ReactiveEngine (engine v2, Fase 2): the concrete engine instance plus the node types that bridge the engine graph to the package's registry-based world. - ObserverInspector
-
Pluggable observability hook for
all_observer. Implement this (or use the bundledConsoleInspector/RecordingInspector) and register instances viaObserverConfig.inspectorsto observe every create/update/dispose/track/warning/effect-run event the package emits, without depending on the hardcoded console logging. - ReactiveScope
-
An ambient disposal scope: every
Computed/CoreComputed,effect()and worker (ever,once,debounce,interval) created inside run registers its own disposer here automatically, so a single call to dispose tears all of them down at once — no hand-rolled list of disposers, no forgottenclose(). - RecordingInspector
- An ObserverInspector that records every event it receives in memory, bounded by maxEvents. Useful as a lightweight audit trail, and for asserting exactly which notifications fired in a test — without the hardcoded console logging noise.
- RegistrySignalNode
-
Engine identity of a
ListenerRegistry-backed source (observable, collection, …). Markedmutable | dirtyat notification time; pulling it simply confirms "yes, it changed" — the actual value equality was already filtered by the owner before notifying. - ScopeDisposeEvent
-
Emitted when a
ReactiveScopeis disposed, noting how many registered disposers ran. - TrackEvent
-
Emitted when an Observer/
Computed/Effect(identified by trackerLabel) reads an observable (identified byObservableEvent.label) for the first time in a given run, establishing a dependency. - TrackingContext
- A single frame of the tracking stack, created while an Observer (or similar consumer) runs its builder.
- WarningEvent
-
Emitted for a misuse warning (empty Observer/
Effect, write during build, possible listener leak, write after dispose, ...). - WatcherNode
-
Effect-like node bridging engine invalidation to external listener
notification for a
CoreComputedthat currently has listeners.
Enums
- ObserverLogLevel
- Controls which categories of informational logs are emitted when ObserverConfig.logging is enabled.
Mixins
- ScopedObserverMixin
-
Mixin for plain Dart classes (controllers, stores, services) that own
reactive resources and want them disposed with a single call — the
pure-Dart counterpart of
ObserverStateMixin, with noState, noBuildContext, and nopackage:flutterimport.
Constants
- kMaxFlushWaves → const int
-
Maximum number of flush waves (full drain cycles of
_pending+_dirtyFlushCallbacks) beforeBatchScope._flushPendingaborts with a descriptive error. Each wave corresponds to one complete pass where every pending registry and every dirty-flush callback run; a legitimate notification cascade needs as many waves as the longest dependency chain. 100 is far more than any real-world graph depth and keeps the total work bounded. - kMaxNotificationDepth → const int
- Maximum notification depth allowed before ListenerRegistry.notifyAll aborts with a descriptive error instead of overflowing the call stack. Guards against update cycles (a listener of A writing B, whose listener writes back to A, forever).
Functions
-
dispatchToInspectors(
List< ObserverInspector> inspectors, void call(ObserverInspector inspector)) → void -
Safely notifies every inspector in
inspectorsofcall, isolating any exception an individual inspector throws (silently, in this pure-Dart core helper — the Flutter layer'sObserverLoggerwraps this with its own colored debug-console report on top). Shared by any core file that needs to fan out an event without importing Flutter. -
disposeAllDepsInReverse(
ReactiveNode sub) → void -
Unlinks every dependency of
sub, newest first. -
purgeDeps(
ReactiveNode sub) → void -
Unlinks every dependency of
subafter its re-tracking cursor (depsTail) — i.e. the dependencies not re-confirmed by the latest run. -
untracked<
T> (T action()) → T -
Runs
actionand returns its result without registering any observable it reads as a dependency of whatever Observer/Computed/Effectis currently tracking (if any). Use this when you need to read a value inside a tracked callback without subscribing to it — most commonly inside aneffect()that writes to one observable based on reading another one it does not want to re-run for.
Typedefs
- Disposer = void Function()
- A function that removes a previously registered listener.
-
ObserverCallback<
T> = void Function(T value) - Callback invoked with the new value of an observable.
- ObserverVoidCallback = void Function()
-
Signature reused across the package for "no arguments, no return"
notifications. Alias kept for readability at call sites. Structurally
identical to Flutter's
VoidCallback(void Function()), so anyObservable/Computedstill satisfiesValueListenable'saddListener/removeListenercontract without this file needing to import Flutter.
Exceptions / Errors
- ObserverCycleError
-
Thrown/reported (via
CoreErrorReporting) when the package detects a possible update cycle — a listener of one observable writing to another whose listener writes back, forever — and aborts instead of recursing or looping indefinitely. SeekMaxNotificationDepth(recursive call-stack cycles, outside any batch) andkMaxFlushWaves(iterative cycles inside anObservable.batch()). - ObserverError
-
Thrown only when
ObserverConfig.strictModeis enabled, in place of the default non-fatal warning, when an Observer builder reads no observable and therefore would never rebuild.