Getting started
Create a graph, store state in signals, derive values with memos, and use effects to connect that state to your application.
Starting a desktop app, or comparing this with FSharp.Data.Adaptive? Read Ranvier or Adaptive for a desktop app? for a complete window and practical workflows. Examples lists complete F# and C# applications to clone and run.
A first graph
open Ranvier
let graph = new Graph()
A signal holds a value let count = createSignal 1.
A memo derives a value let doubled = createMemo (fun _ -> count.Value * 2).
And an effect runs when what it read changes:
graph.Run (fun () ->
let count = createSignal 1
let doubled = createMemo (fun _ -> count.Value * 2)
createEffect (fun () -> printfn "doubled = %d" doubled.Value)
count.Value <- 5
doubled)
Example code
let count = createSignal 1
let doubled = createMemo (fun _ -> count.Value * 2)
createEffect (fun () -> printfn $"doubled = %d{doubled.Value}")
controls [
button "Set" (fun () -> count.Value <- 5)
|> describe "The write refreshes doubled from 2 to 10."
|> expect "The write refreshes doubled from 2 to 10." (fun () -> doubled.Peek = 10)
]
Make the graph active
The create* functions use the active graph. graph.Run activates it for the body and restores the previous graph afterward. For a longer scope, keep the handle returned by graph.Activate ():
open Ranvier
use graph = new Graph ()
use active = graph.Activate ()
let count = createSignal 1
let doubled = createMemo (fun _ -> count.Value * 2)
createEffect (fun () -> printfn "doubled = %d" doubled.Value)
count.Value <- 5
Disposing the graph releases its computations and runs their cleanups. In an application, keep the graph alive for as long as its state is needed.
Choose the next concept
- Graphs: activation, explicit construction and graph configuration.
- Signals: tracked reads, writes and equality.
- Memos: lazy derived values, previous values and dynamic dependencies.
- Effects: external work, scheduling and failures.
- Roots and owners and Cleanup: lifetimes and resource release.
- Untrack: read current values without subscribing.
- Batch: combine writes into one effect flush.
- Editable values and Drafts: local edits over upstream state.
Continue with Async and pending for loading and errors, or Collections for per-row reactivity and aggregates.