Files
livevue-rs/examples/todo/main.rs
T
Claude 8535d39012 Refactor: untangle framework library from todo example
The codebase is now split into two clear layers:

Framework library (src/):
- lib.rs — public API surface, re-exports all framework types
- signal.rs — SignalOpts, Signal, SignalStore, mangle/global/client_only helpers
- query.rs — Query trait, CacheKey, query_one!/query_all! macros
  (macro paths updated from $crate::framework::* to $crate::*)
- context.rs — RenderContext, ComponentTree, ComponentNode
- connection.rs — ConnectionManager, SubscriptionRegistry, ConnectionState
- sse.rs — format_patch_elements, format_patch_signals
- server.rs — AppState, SharedState, sse_handler (pure framework plumbing)

Todo example (examples/todo/):
- main.rs — SQLite setup, seeding, server bootstrap
- app.rs — router, document_shell, resolve_and_render, render_page,
  action_then_render, and all HTTP handlers
- queries.rs — Todo model, ListTodos/GetTodo queries, mutation helpers
- todo_list.rs — TodoList page component
- about.rs — About page component

Run the example independently with: cargo run --example todo

https://claude.ai/code/session_01JThiQbp3Bn9J1VhBpRuz4u
2026-03-06 16:51:53 +00:00

65 lines
2.0 KiB
Rust

mod app;
mod queries;
mod todo_list;
mod about;
use livevue_rs::{AppState, ConnectionManager, SubscriptionRegistry};
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// -----------------------------------------------------------------------
// Database setup
// -----------------------------------------------------------------------
// SQLite with create-if-missing. In-memory `:memory:` also works for dev.
let db = sqlx::SqlitePool::connect("sqlite:todo.db?mode=rwc").await?;
// Run migrations inline (no migration files needed for v0).
sqlx::query(
"CREATE TABLE IF NOT EXISTS todos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)",
)
.execute(&db)
.await?;
// Seed a few todos if the table is empty (nice for first run)
let count: (i64,) = sqlx::query_as("SELECT COUNT(*) FROM todos")
.fetch_one(&db)
.await?;
if count.0 == 0 {
for title in &["Learn Rust", "Build LiveVue.rs", "Ship v0"] {
sqlx::query("INSERT INTO todos (title, completed) VALUES (?, false)")
.bind(title)
.execute(&db)
.await?;
}
}
// -----------------------------------------------------------------------
// Application state
// -----------------------------------------------------------------------
let state = Arc::new(AppState {
db,
connections: ConnectionManager::new(),
subscriptions: SubscriptionRegistry::new(),
});
// -----------------------------------------------------------------------
// Server
// -----------------------------------------------------------------------
let app = app::router(state);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
println!("Todo example listening on http://localhost:3000");
axum::serve(listener, app).await?;
Ok(())
}