conversions
Functions for converting between Behaviors and Streams.
changes
Converts a Behavior to a Stream that emits whenever the value changes.
Signature
function changes<A>(behavior: Behavior<A>): Stream<Signal<"behavior-change", A>>Example
import { stepper, changes } from "cereb/frp";
const position = stepper({ x: 0, y: 0 }, pointerStream, (s) => s.value);
// Convert to a stream of changesconst positionChanges = changes(position);
positionChanges.on((signal) => { console.log("Position changed to:", signal.value);});Parameters
| Parameter | Type | Description |
|---|---|---|
behavior | Behavior<A> | The behavior to observe |
Returns
A Stream<Signal<"behavior-change", A>> that emits when the behavior’s value changes.
Notes
- Does not emit for constant behaviors (they never change)
- Emits immediately when the underlying source changes
sample
Samples a Behavior at regular intervals.
Signature
function sample<A>(behavior: Behavior<A>, intervalMs: number): Stream<Signal<"sampled", A>>Example
import { time, sample } from "cereb/frp";
const t = time();
// Sample time every 100msconst timeSamples = sample(t, 100);
timeSamples.on((signal) => { console.log("Time:", signal.value);});Parameters
| Parameter | Type | Description |
|---|---|---|
behavior | Behavior<A> | The behavior to sample |
intervalMs | number | Sampling interval in milliseconds |
Returns
A Stream<Signal<"sampled", A>> that emits at each interval.
Notes
- Uses
setIntervalinternally - Unsubscribing clears the interval
sampleOn
Samples a Behavior whenever a trigger Stream fires.
Signature
function sampleOn<A, S extends Signal>( behavior: Behavior<A>, trigger: Stream<S>): Stream<Signal<"sampled-on", { value: A; trigger: S }>>Example
import { constant, sampleOn } from "cereb/frp";import { dom } from "cereb";
const counter = stepper(0, incrementStream, (s) => s.value);const clicks = dom(button, "click");
// Sample counter value on each clickconst counterOnClick = sampleOn(counter, clicks);
counterOnClick.on((signal) => { console.log("Counter at click:", signal.value.value); console.log("Click event:", signal.value.trigger);});Parameters
| Parameter | Type | Description |
|---|---|---|
behavior | Behavior<A> | The behavior to sample |
trigger | Stream<S> | The trigger stream |
Returns
A Stream<Signal<"sampled-on", { value: A; trigger: S }>> containing both the sampled value and the trigger signal.
animationFrame
Samples a Behavior on every animation frame using requestAnimationFrame.
Signature
function animationFrame<A>(behavior: Behavior<A>): Stream<Signal<"frame", { value: A; timestamp: number }>>Example
import { combine, animationFrame } from "cereb/frp";
const transform = combine( positionBehavior, scaleBehavior, (pos, scale) => `translate(${pos.x}px, ${pos.y}px) scale(${scale})`);
// Render on every frameconst unsubscribe = animationFrame(transform).on(({ value }) => { element.style.transform = value.value;});
// Later: stop the animation loopunsubscribe();Parameters
| Parameter | Type | Description |
|---|---|---|
behavior | Behavior<A> | The behavior to sample |
Returns
A Stream<Signal<"frame", { value: A; timestamp: number }>> that emits on each animation frame with the sampled value and the frame timestamp.
Notes
- Ideal for smooth animations at 60fps
- Unsubscribing cancels the animation frame loop
elapsedTime
Creates a Behavior that tracks elapsed time since creation, updating every animation frame.
Signature
function elapsedTime(): { elapsed: Behavior<number>; dispose: () => void }Example
import { elapsedTime } from "cereb/frp";
const { elapsed, dispose } = elapsedTime();
// Sample elapsed timeconsole.log("Elapsed:", elapsed.sample()); // 0// ... later ...console.log("Elapsed:", elapsed.sample()); // e.g., 1234.56
// Use with animationselapsed.onChange((t) => { const progress = Math.min(t / 1000, 1); // 0 to 1 over 1 second element.style.opacity = String(progress);});
// Clean up when donedispose();Returns
An object with:
| Property | Type | Description |
|---|---|---|
elapsed | Behavior<number> | Elapsed time in milliseconds |
dispose | () => void | Function to stop tracking and clean up |
Notes
- Updates via
requestAnimationFrameinternally - Call
dispose()to stop the animation loop and clean up resources