refactor(saas): make navigation and status idiomatic

Use a real enhanceable Settings URL, remove response-simulated navigation, and replace the one-shot public SSE endpoint with an initial canonical event plus ongoing server-owned updates. Keep a bounded one-event probe for production-reference tests.

req: examples/014

req: nav/001

req: nav/002

req: nav/004

req: push/003
This commit is contained in:
slhx agent
2026-07-22 18:18:48 +02:00
parent c4a6edfed1
commit 276f40ee59
7 changed files with 59 additions and 73 deletions
+15 -9
View File
@@ -5,14 +5,14 @@ use axum::middleware::{self, Next};
use axum::response::{IntoResponse, Response};
use axum::routing::{get, post};
use axum::Router;
use futures_util::stream;
use futures_util::{stream, StreamExt};
use hemx::IntoEffect;
use hemx_axum::{runtime_js, runtime_js_path, sse, EffectResponse, InteractionRequest};
use hemx_saas_example::{home_page, live_status, registry, settings_page, ui, AppContext};
use std::collections::BTreeMap;
use std::convert::Infallible;
use std::path::PathBuf;
use std::time::Instant;
use std::time::{Duration, Instant};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -81,16 +81,22 @@ async fn events(
Query(params): Query<BTreeMap<String, String>>,
State(ctx): State<AppContext>,
) -> impl IntoResponse {
let count = ctx.projects().len();
// The production reference exposes an ongoing server-owned stream; `once`
// keeps a bounded probe for package tests without changing the public path.
// req: examples/014
let event = |ctx: &AppContext| {
Ok::<_, Infallible>(live_status(ctx.projects().len()).into_batch(ui::BUILD_FINGERPRINT))
};
let initial = stream::once(std::future::ready(event(&ctx)));
if params.contains_key("once") {
return sse(stream::iter([Ok::<_, Infallible>(
live_status(count).into_batch(ui::BUILD_FINGERPRINT),
)]));
return sse(initial.left_stream());
}
sse(stream::iter([Ok::<_, Infallible>(
live_status(count).into_batch(ui::BUILD_FINGERPRINT),
)]))
let updates = stream::unfold(ctx, move |ctx| async move {
tokio::time::sleep(Duration::from_secs(15)).await;
Some((event(&ctx), ctx))
});
sse(initial.chain(updates).right_stream())
}
// req: auth/001 req: auth/002 req: auth/004