35 releases

Uses new Rust 2024

0.7.23 Feb 17, 2026
0.7.20 Jan 30, 2026
0.7.12 Dec 30, 2025
0.7.3 Nov 26, 2025
0.5.2 Jul 29, 2025

#908 in WebAssembly

Download history 17/week @ 2025-12-24 22/week @ 2025-12-31 40/week @ 2026-01-07 31/week @ 2026-01-14 23/week @ 2026-01-21 92/week @ 2026-01-28 14/week @ 2026-02-04 89/week @ 2026-02-11 6/week @ 2026-02-18 8/week @ 2026-02-25 11/week @ 2026-03-04 15/week @ 2026-03-11 15/week @ 2026-03-18 11/week @ 2026-03-25 15/week @ 2026-04-01 15/week @ 2026-04-08

56 downloads per month
Used in 12 crates (4 directly)

MIT/Apache

105KB
1.5K SLoC

Ankurah Signals

A signals library for the Ankurah distributed database. Inspired by Preact signals and designed specifically for Ankurah's needs, supporting both native Rust and WebAssembly/React usage.

Basic Usage in Rust

use ankurah_signals::{Mut, Subscribe, CallbackObserver};
use std::sync::Arc;

let day = Mut::new("Friday");
let vibe = Mut::new("grindcore");

// Sometimes directly subscribing to the signal can be useful
// your listener will not be called immediately, only when the signal changes
// the subscription will be removed when the SubscriptionGuard is dropped
let _guard1 = day.subscribe(|v| println!("The day is: {}", v));
let _guard2 = vibe.subscribe(|v| println!("Vibe: {}", v));

// For things that need to track signal dependencies, we can use an Observer
let renderer = {
    let day = day.read(); // Read<T> signals can be constructed from a Mut<T> signal
    let vibe = vibe.read();
    CallbackObserver::new(Arc::new(move ||{
        // Your "render" function that uses signals
        // The Observer will automatically subscribe to the signals used
        // during this dispatch using the thread-local CurrentObserver
        println!("It's {day} and I'm {vibe}")
    }))
};

renderer.trigger(); // trigger the initial "render". Signals used will be tracked by the observer.
// Should print:
// It's Friday and I'm grindcore

vibe.set("chillmaxing"); // triggers the direct signal subscription AND the observer
// Should print:
// Vibe: chillmaxing
// It's Friday and I'm chillmaxing

day.set("Saturday");
// Should print:
// The day is: Saturday
// It's Saturday and I'm chillmaxing

Basic Usage in React

You should have a rust crate that exports the wasm bindings to your react app. You will need to include the ankurah-signals crate with the react feature enabled.

[dependencies]
ankurah-signals = { version = "0.1", features = ["react"] }

React Component Pattern

import { useObserve } from "my_wasm_bindgen_crate";

function MyComponent({ currentTime }: { currentTime: StringRead }) {
  const observer = useObserve();

  try {
    return (
      <div>
        <p>The time is: {currentTime.get()}</p>
      </div>
    );
  } finally {
    observer.finish();
  }
}

// this will be made more ergonomic in the future using a vite preprocessor to add this automatically
// in the meahwhile, you can make a helper function if desired:
import { useObserve } from "my_wasm_bindgen_crate";

export function signalObserver<T>(f: React.FC<T>): React.FC<T> {
  return (props: T) => {
    const observer = useObserve();
    try {
      return f(props);
    } finally {
      observer.finish();
    }
  };
}

export const MyComponent = signalObserver(({ fooSignal }: MyProps) => {
  return (
    <div>
      <p>The foo is: {fooSignal.value}</p>
      {/* fooSignal is tracked by the ReactObserver, and MyComponent will
      be re-rendered when fooSignal changes */}
    </div>
  );
});

Dependencies

~6–16MB
~233K SLoC