teksilo-async — optional main-thread async executor for Teksilo
Teksilo keeps the view layer synchronous: "async is the backend's concern."
Most background→UI flows are best served by the reactive data path
(ctx.subscribe_event(...) + Signal::set). This crate is the opt-in
escape hatch for the cases that want imperative async — writing linear
async / .await inside a handler, sequencing several awaits in one place.
use teksilo_async::{TeksiloAppBuilderAsyncExt, EventContextAsyncExt, spawn_blocking};
TeksiloAppBuilder::new().install_async() /* ... */ .run();
// inside a handler:
let status = self.status.clone(); // Signal<Status> (Rc clone)
ctx.spawn_local(async move {
status.set(Status::Loading);
let bytes = spawn_blocking(move || std::fs::read(path)).await;
status.set(Status::from(bytes)); // resume on the UI thread → set Signal
})
.detach();
Model
- The executor is single-threaded and
!Send;spawn_localfutures live on the UI thread and captureRc-basedSignals, mutating them on resume. There is noEventContextafter.await(it is borrow-transient), so UI updates flow through owned handles (Signals) — the reactive model. - For a one-shot ambient op after the work finishes (
open_window,send_intent, …),spawn_local_withdelivers the result to a callback with a freshEventContext. - [
spawn_blocking] offloads blocking work to an OS thread and awaits the result — no async runtime required.
The executor is driven once per event-loop turn via the async-agnostic
on_loop_tick hook; it
sleeps (zero idle CPU) until a task is woken, including from a
spawn_blocking worker thread.
teksilo-tokio / teksilo-async-std build on this crate to add reactor
support so native-ecosystem futures (tokio::time, sockets, reqwest, …)
can be .awaited directly in UI code.