Reactive Engine
@azmr/core
signal<number>
count0
↓ computed
computed — count × 2
doubled0
computed — count²
squared0
typescript
import { Signal, computed } from "@azmr/core"; import { useSignal } from "@azmr/ui"; // Source signal const count = new Signal(0); // Derived signals — update automatically const doubled = computed(() => count.get() * 2); const squared = computed(() => count.get() * count.get()); function Counter() { const value = useSignal(count); const dbl = useSignal(doubled); const sqr = useSignal(squared); return ( <> <p>count: {value}</p> <p>doubled: {dbl}</p> <p>squared: {sqr}</p> <button onClick={() => count.set(count.peek() + 1)}>+</button> <button onClick={() => count.set(count.peek() - 1)}>−</button> <button onClick={() => count.set(0)}>reset</button> </> ); }
Query Engine
@azmr/query
| name | city | balance |
|---|---|---|
| Mere | AKL | $320 |
| Aroha | WLG | $150 |
| Rangi | CHC | $75 |
| Tane | AKL | $0 |
typescript
import { Signal } from "@azmr/core"; import { query } from "@azmr/query"; const minBalance = new Signal(0); const customers = [ { name: "Aroha", city: "WLG", balance: 150 }, { name: "Tane", city: "AKL", balance: 0 }, { name: "Mere", city: "AKL", balance: 320 }, { name: "Hemi", city: "CHC", balance: -10 }, { name: "Rangi", city: "CHC", balance: 75 }, ]; // Re-runs in render whenever minBalance signal changes const results = query(customers) .where(c => c.balance >= minBalance.get()) .orderBy((a, b) => b.balance - a.balance) .select(); // → filtered + sorted array, no boilerplate
Reactive Grid
3 records
signal<Product[]> → @azmr/ui Grid
| name | price | in stock |
|---|---|---|
| Widget A | $29.99 | yes |
| Widget B | $49.99 | no |
| Widget C | $9.99 | yes |
typescript
import { Signal } from "@azmr/core"; import { useSignal } from "@azmr/ui"; type Product = { name: string; price: number; inStock: boolean }; const products = new Signal<Product[]>([ { name: "Widget A", price: 29.99, inStock: true }, { name: "Widget B", price: 49.99, inStock: false }, { name: "Widget C", price: 9.99, inStock: true }, ]); function ProductGrid() { const data = useSignal(products); const addProduct = () => products.set([...products.peek(), newProduct]); const removeLast = () => products.set(products.peek().slice(0, -1)); // Grid re-renders automatically on every signal change return <Grid signal={products} />; }