Skip to main content

Module reactive

Module reactive 

Source
Expand description

The reactive core, whole (docs/async.md): day::reactive::{Resource, Load} for async data loading. Namespaced because the prelude’s Resource is the asset handle above, a different type that predates the async one.

Macros§

tls_group
tls_root
tls_slots
One module’s slots, stored as $field of the crate’s tls_root!.

Structs§

AnyBinding
A type-erased Binding: what a piece stores when its builder takes impl Binding<T> (docs/api-style.md “Three input spellings”), so the piece itself needs no type parameter per bound value.
Effect
A reaction that re-runs when its tracked reads change. Runs once at creation.
Memo
Cached, equality-diffed derived value (§4.2).
NodeKey
Resource
Declarative async data loading (§4.5): a tracked source whose value feeds an async fetcher; the result lands in a Signal<Load<T>>. The source re-runs when its tracked reads change; an unchanged source value refetches nothing, Resource::refetch always does. Latest wins: a source change supersedes the in-flight fetch (aborting its task; dropping any FetchFuture inside cancels the platform request) and a stale completion writes nothing. Scope disposal aborts the in-flight fetch the same way.
RunId
The identity of one reactive computation (a reaction or a memo) across its lifetime. Opaque; Copy + Eq + Hash, so an external dependency registry can key per-computation bookkeeping on it. Slotmap-generational underneath: a recycled slot is a new RunId.
Scope
Ownership scope for signals/effects (§4.3). Copy handle; not Send.
ScopeKey
Setter
Send write-only handle to a signal; delivery hops to the UI thread via the main poster. Writes after disposal are silent no-ops (§4.3).
Signal
A Copy, !Send reactive value handle (§4.2).
Trigger
Data-less invalidation source.

Enums§

Load
The lifecycle of an async-loaded value. Failed carries the fetcher’s error as a shared trait object so Load stays Clone for signal reads.

Traits§

Binding
A readable-writable value a control can bind to two-way: a Signal, or any projection that knows how to read and write its own slot (day-model’s Field is the other implementor).

Functions§

active_run
The computation currently tracking reads: None at top level and under untrack.
at_turn_end
Run cb once, when the current turn settles: after the drain inside a drain or a batch (even a batch that leaves no reactive work behind), or right away when no turn is open.
batch
bind
The binding primitive (§4.2): compute (tracked) + apply (untracked), equality-gated. Structural priority: bindings drain before plain effects. apply receives the new value by reference so V needs only PartialEq (no Clone).
bind_always
bind for payloads without PartialEq, applying on every recompute.
bind_seeded
bind pre-seeded with the value already applied at build time: the initial run does not re-apply (pieces pass initial values through realize props; §5.2’s no-duplicate-op rule).
flush_now
Force a synchronous fixpoint drain now, even inside an open batch. Event dispatch wraps handlers in a batch (day-core), so a handler that needs its writes to drain immediately (namely with_animation, whose ambient animation must be live while the resulting patches apply) cannot rely on the batch’s close (that runs later, after the scope ends). This temporarily drops the batch depth so flush_sync runs, then restores it. No-op if a drain is already in progress (the writes fold into it); harmless if nothing is pending.
flush_sync
Drain the pending queue to fixpoint, then run turn-end callbacks (§3.3 steps 2–3), repeating both until the turn is quiescent. A turn-end callback may schedule new reactive work (day-persistence’s autosave flush re-derives live queries and diffs the answers into signals); that work belongs to this turn: §3.3 step 2’s “writes made during the drain extend the current drain”, extended across the turn-end boundary. Left pending instead, every cross-row readout (a query-fed list, a derived bound) would render one turn stale. Round two drains the deltas and re-runs the hooks, and autosave then finds nothing dirty, so a settled app exits after two rounds; The turn-round cap stops turn-end hooks that feed each other forever.
has_main_poster
Whether a backend has installed the main poster yet, i.e. whether on_main would work rather than panic. Platform glue that can be called before launch (a notification tap that cold-starts the process) probes this and buffers instead of posting. The poster is set once and never cleared, so a false can only become true: a caller that buffers on a false negative is still correct, provided something drains the buffer at launch.
install_delayed_poster
Install the timer door (Platform::post_delayed). Backends call this once at startup.
install_main_poster
Install the cross-thread → main-thread door. Backends call this once at startup.
install_scheduler
Install “post a drain on the main loop”. Backends call this once at startup.
install_spawner
Install the async-spawn door: spawn runs a future on the app’s main-loop executor and returns an abort closure (remove + drop the future). The abort must be a no-op once the task has completed: Resource stores it after an eager first poll, so a synchronously ready future has already finished by then. day-core’s launch_with wires this to day::task / TaskHandle::abort; call it once at startup (docs/async.md).
on_main
Schedule f on the UI thread (usable from any thread once a backend installed the poster).
on_main_delayed
Schedule f on the UI thread after (at least) ms milliseconds, the rail behind day::sleep (docs/async.md).
on_run_retrack
Hang f on the active computation’s current run: it fires when that computation next re-tracks (a re-run clears its sources first) or is disposed. This is the hook that lets an external dependency registry (day-model’s trigger claims) mirror this graph’s per-run source bookkeeping. Returns false, registering nothing, when no computation is tracking.
on_turn_end
Register a callback run once after every fixpoint drain (day-core’s layout turn).
recover_from_panic
Reset the runtime to a clean idle state after a panic unwound through a drain or batch, e.g. a reactive-cycle assertion (the rerun cap) that tripped inside a native event callback which the backend contained (rather than letting it abort the process across the C ABI; a GTK/Qt signal trampoline can’t unwind). The in-flight pending work and the observer stack are dropped (the next interaction re-derives them); persistent registrations (effects, memos, turn-end hooks) are kept.
untrack
Run f without tracking reads.
watch
Derive-state without effect-write loops (§4.2): source is tracked; cb runs untracked with (new, old). Does not fire for the initial value: a “load whatever is selected” reaction has to run once by hand first, or use bind, which applies the initial value and then every change.

Type Aliases§

LocalBoxFuture
A boxed, !Send future for the install_spawner executor door.