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§
Structs§
- AnyBinding
- A type-erased
Binding: what a piece stores when its builder takesimpl 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
sourcewhose value feeds an asyncfetcher; the result lands in aSignal<Load<T>>. The source re-runs when its tracked reads change; an unchanged source value refetches nothing,Resource::refetchalways does. Latest wins: a source change supersedes the in-flight fetch (aborting its task; dropping anyFetchFutureinside 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 newRunId. - Scope
- Ownership scope for signals/effects (§4.3).
Copyhandle; notSend. - Scope
Key - Setter
Sendwrite-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,!Sendreactive value handle (§4.2). - Trigger
- Data-less invalidation source.
Enums§
- Load
- The lifecycle of an async-loaded value.
Failedcarries the fetcher’s error as a shared trait object soLoadstaysClonefor 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’sFieldis the other implementor).
Functions§
- active_
run - The computation currently tracking reads:
Noneat top level and underuntrack. - at_
turn_ end - Run
cbonce, 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.
applyreceives the new value by reference soVneeds onlyPartialEq(noClone). - bind_
always bindfor payloads withoutPartialEq, applying on every recompute.- bind_
seeded bindpre-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 (namelywith_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 soflush_syncruns, 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_mainwould 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 afalsecan only becometrue: 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:
spawnruns 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:Resourcestores it after an eager first poll, so a synchronously ready future has already finished by then. day-core’slaunch_withwires this today::task/TaskHandle::abort; call it once at startup (docs/async.md). - on_main
- Schedule
fon the UI thread (usable from any thread once a backend installed the poster). - on_
main_ delayed - Schedule
fon the UI thread after (at least)msmilliseconds, the rail behindday::sleep(docs/async.md). - on_
run_ retrack - Hang
fon 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. Returnsfalse, 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
pendingwork and the observer stack are dropped (the next interaction re-derives them); persistent registrations (effects, memos, turn-end hooks) are kept. - untrack
- Run
fwithout tracking reads. - watch
- Derive-state without effect-write loops (§4.2):
sourceis tracked;cbruns 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 usebind, which applies the initial value and then every change.
Type Aliases§
- Local
BoxFuture - A boxed,
!Sendfuture for theinstall_spawnerexecutor door.