app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 6dc33b3c07b909f49cece37565ca5ed39193e838
parent d594abeb71ad7a2b6f04b7220e088daead59e0d8
Author: triesap <triesap@radroots.dev>
Date:   Mon, 19 Jan 2026 16:49:44 +0000

app: add app context helper for init signals

- define AppContext wrapper for init/backends signals
- add app_context helper to fetch provided signals
- add tests for context presence and defaults
- export context helpers from app crate

Diffstat:
Aapp/src/context.rs | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mapp/src/lib.rs | 2++
2 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/app/src/context.rs b/app/src/context.rs @@ -0,0 +1,53 @@ +#![forbid(unsafe_code)] + +use leptos::prelude::{use_context, LocalStorage, RwSignal}; + +use crate::{AppBackends, AppInitError, AppInitState}; + +#[derive(Clone)] +pub struct AppContext { + pub backends: RwSignal<Option<AppBackends>, LocalStorage>, + pub init_error: RwSignal<Option<AppInitError>, LocalStorage>, + pub init_state: RwSignal<AppInitState, LocalStorage>, +} + +pub fn app_context() -> Option<AppContext> { + Some(AppContext { + backends: use_context::<RwSignal<Option<AppBackends>, LocalStorage>>()?, + init_error: use_context::<RwSignal<Option<AppInitError>, LocalStorage>>()?, + init_state: use_context::<RwSignal<AppInitState, LocalStorage>>()?, + }) +} + +#[cfg(test)] +mod tests { + use super::app_context; + use crate::{app_init_state_default, AppBackends, AppInitError, AppInitStage}; + use leptos::prelude::{provide_context, Owner, RwSignal, WithUntracked}; + + #[test] + fn app_context_is_none_without_providers() { + let owner = Owner::new(); + owner.set(); + assert!(app_context().is_none()); + } + + #[test] + fn app_context_reads_provided_signals() { + let owner = Owner::new(); + owner.set(); + let backends = RwSignal::new_local(None::<AppBackends>); + let init_error = RwSignal::new_local(None::<AppInitError>); + let init_state = RwSignal::new_local(app_init_state_default()); + provide_context(backends); + provide_context(init_error); + provide_context(init_state); + let context = app_context().expect("context"); + assert!(context.backends.with_untracked(|value| value.is_none())); + assert!(context.init_error.with_untracked(|value| value.is_none())); + assert_eq!( + context.init_state.with_untracked(|state| state.stage), + AppInitStage::Idle + ); + } +} diff --git a/app/src/lib.rs b/app/src/lib.rs @@ -1,10 +1,12 @@ #![forbid(unsafe_code)] mod app; +mod context; mod init; mod entry; pub use app::App; +pub use context::{app_context, AppContext}; pub use init::{ app_init_backends, app_init_has_completed,