Tincan
Overview
A fine-grained reactive state management library for Rust.
Tincan provides two levels of abstraction for building reactive applications:
- Signals: Low-level reactive primitives with automatic dependency tracking and functional combinators
- Store: High-level state management for complex application state
Core Concepts
- Signal: A reactive value with combinator methods (map, zip) for composing transformations
- Memo: A cached computed value that only recalculates when dependencies change
- Effect: A side effect that automatically runs when dependencies change, with automatic cleanup
- Store: A container for complex state with automatic change notifications
Quick Start
Signals
use Signal;
// Create a reactive signal
let count = new;
// Transform with combinators (like Iterator)
let doubled = count.map;
// Watch for changes (returns guard for automatic cleanup)
let _guard = doubled.watch;
// Update the signal (triggers watcher automatically)
count.set; // Prints: "Doubled: 10"
Combining Multiple Signals
use Signal;
let first = new;
let second = new;
// Combine signals with zip
let sum = first.clone.zip
.map;
println!; // Sum: 3
// Updates propagate automatically
first.set;
println!; // Sum: 12
Memos for Expensive Computations
use ;
let count = new;
let expensive_double = new;
println!; // Prints: "Computing..." then "10"
println!; // Uses cached value, no "Computing..."
count.set; // Marks memo as dirty
println!; // Prints: "Computing..." then "20"
Effects for Side Effects
use ;
let count = new;
// Create an effect that runs when dependencies change
let _effect = new;
// Prints immediately: "Count is now: 0"
count.set; // Prints: "Count is now: 5"
count.set; // Prints: "Count is now: 10"
// Effect is automatically cleaned up when dropped
Store (High-level API)
use Store;
// Create a store
let store = new;
// Subscribe to changes
store.subscribe;
// Update state
store.update;
API Overview
Signal Methods
let signal = new;
// Reading
signal.get // Clone the current value
signal.with // Read without cloning
// Writing
signal.set // Set a new value
signal.update // Update based on current value
// Transformations
signal.map // Create derived signal
signal.zip // Combine with another signal
// Watching
signal.watch // Returns WatchGuard (auto-cleanup)
Memo Methods
let memo = new;
memo.get // Get value (recompute if dirty)
memo.with // Access without cloning
Effect
new;
// Auto-cleanup on drop
Store Methods
let store = new;
store.get // Clone current state
store.set // Replace state
store.update // Mutate state
store.subscribe // Listen to changes
store.read // Read without cloning
Benchmarks
Run performance benchmarks:
License
MIT License - see LICENSE for details.