Added CLAUDE.md

This commit is contained in:
2026-03-22 13:31:29 -04:00
parent 28e140b302
commit bc9aeaf007

69
CLAUDE.md Normal file
View File

@@ -0,0 +1,69 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Build the entire workspace
cargo build
# Run a specific example (all live in lib/ruin_app/example/)
cargo run --example 00_bootstrap_and_counter -p ruin_app
cargo run --example 01_async_data_and_effects -p ruin_app
cargo run --example 03_fine_grained_list -p ruin_app
# Run tests
cargo test
# Run tests for a specific crate
cargo test -p ruin_reactivity
```
## Architecture
RUIN is a layered, single-threaded reactive UI framework targeting Linux/Wayland. The layers build on each other strictly from bottom to top:
### Layer Stack
**`ruin-runtime`** (`lib/runtime/`) — Linux x86_64 async runtime. io_uring-backed I/O, single-threaded event loop with JavaScript-style microtask/macrotask scheduling. Entry points are `#[ruin_runtime::async_main]` and `#[ruin_runtime::main]` macros. Provides `fs::*`, `net::*`, `time::*`, `channel::*` (mpsc, oneshot).
**`ruin_reactivity`** (`lib/reactivity/`) — Fine-grained reactive graph. Key primitives: `Cell` (root signal), `Thunk`/`Memo` (derived values), `Effect` (side-effects), `Event` (subscriptions). The reactor is single-threaded and schedules deferred jobs via the runtime's microtask queue. No async inside the reactive graph — async work feeds results in via state updates at the edges.
**`ruin_ui`** (`lib/ui/`) — Platform/renderer-agnostic UI substrate. Intentionally uses explicit Rust construction (no proc-macros at this layer). Key modules: `layout.rs` (flexbox-style layout engine), `text.rs` (cosmic-text integration), `scene.rs` (display list/scene graph), `interaction.rs` (pointer/keyboard routing), `platform.rs` (platform abstraction traits), `tree.rs` (element tree and styling).
**`ruin_ui_platform_wayland`** (`lib/ui_platform_wayland/`) — Wayland backend. Entry point: `start_wayland_ui()`. Handles window creation, input events, clipboard via wayland-client + wgpu renderer.
**`ruin_ui_renderer_wgpu`** (`lib/ui_renderer_wgpu/`) — GPU rendering via wgpu. Text rasterization with cosmic-text.
**`ruin_app`** (`lib/ruin_app/`) — High-level app/runtime glue. This is the crate most application code targets. Exports `App`, `Window`, `Mountable`, and the proc-macros `#[component]`, `view!`, `#[context_provider]`. **Intentionally low-level** — it is the expansion target for proc-macros, not the final ergonomic API.
**`ruin_app_proc_macros`** (`lib/ruin_app_proc_macros/`) — Procedural macros: `#[component]` wraps component functions, `view!` is the DSL for UI tree construction, `#[context_provider]` injects context values.
### Application Model
A typical app entry point:
```rust
#[ruin_runtime::async_main]
async fn main() -> ruin_app::Result<()> {
App::new()
.window(Window::new().title("My App").app_id("dev.ruin.myapp").size(960.0, 640.0))
.mount(view! { MyRootComponent() {} })
.run()
.await
}
```
Components use `#[component]` and return `impl IntoView`. Reactive state uses `use_signal`, `use_memo`, `use_effect`. Layout uses `view!` with primitives like `column`, `row`, `block`, `text`, `button`.
### The `aspirational_examples/` Directory
These files (`00_` through `07_`) define the **desired future API** — a cleaner `ruin::prelude::*` surface with shorter syntax like `use_signal` instead of `use_signal(|| ...)`. They are **not wired into the build**. The corresponding **ported implementations** live in `lib/ruin_app/example/` and represent the current actual API. When porting an aspirational example, the goal is to make the example/ version match the aspirational design as closely as the current framework allows.
### Key Design Constraints
- The reactive graph is strictly single-threaded — never share reactive values across threads.
- `Signal<T>` must be `.clone()`d before being moved into closures (it's `Rc`-based, not `Arc`).
- All float layout values are `f32` (e.g., `gap = 8.0`, not `gap = 8`).
- `ruin_app` is the integration target; avoid bypassing it to call `ruin_ui` or `ruin_reactivity` directly in application code unless writing low-level infrastructure.