26 releases (breaking)

new 0.20.0 Jan 11, 2025
0.18.2 Jan 7, 2025
0.14.0 Dec 20, 2024
0.12.0 Nov 11, 2024
0.9.0 Jul 3, 2024

#89 in Concurrency

Download history 61/week @ 2024-09-21 72/week @ 2024-09-28 188/week @ 2024-10-05 69/week @ 2024-10-12 197/week @ 2024-10-19 19/week @ 2024-10-26 73/week @ 2024-11-02 178/week @ 2024-11-09 15/week @ 2024-11-16 23/week @ 2024-11-23 15/week @ 2024-11-30 58/week @ 2024-12-07 395/week @ 2024-12-14 215/week @ 2024-12-21 321/week @ 2024-12-28 615/week @ 2025-01-04

1,555 downloads per month

Custom license

120KB
2.5K SLoC

rs-store

Crates.io Documentation License: MIT

A thread-safe Redux-style state management library implemented in Rust.

Overview

rs-store provides a predictable state container inspired by Redux, featuring thread-safe state management with support for reducers, subscribers, and async actions through Thunk. Unlike traditional Redux, rs-store's reducers can produce side effects, providing more flexibility in state management.

Features

  • ๐Ÿ”’ Thread-safe state management
  • ๐Ÿ“ข Publisher/Subscriber pattern for state changes
  • ๐Ÿ”„ Support for asynchronous operations via Thunk actions
  • ๐Ÿ“Š Side effect handling in reducers
  • ๐Ÿ“Š Middleware handles actions and effects
  • ๐Ÿ“Š Backpressure handling with configurable policies
  • ๐ŸŽฏ Bounded channel size with sync channels
  • ๐Ÿงช Comprehensive test coverage
  • ๐Ÿ“š Selector support
  • ๐Ÿ“Š Metrics support
  • ๐Ÿ”„ Decoupling state updates from notification delivery

Installation

Add this to your Cargo.toml:

[dependencies]
rs-store = "0.20.0"

with the notify-channel feature:

[dependencies]
rs-store = { version = "0.20.0", features = ["notify-channel"] }

Quick Start

use rs_store::{Store, CalcState, CalcAction, CalcReducer, CalcSubscriber};
use std::{thread, sync::Arc};

impl Reducer<CalcState> for CalcReducer {
    fn reduce(&self, state: &CalcState, action: &CalcAction) -> DispatchOp<CalcState, CalcAction> {
        match action {
            CalcAction::Add(value) => {
                println!("Adding value: {}", value);
                DispatchOp::Dispatch(
                    CalcState {
                        value: state.value + value,
                    },
                    None,
                )
            }
            CalcAction::Subtract(value) => {
                println!("Subtracting value: {}", value);
                DispatchOp::Dispatch(
                    CalcState {
                        value: state.value - value,
                    },
                    None,
                )
            }
        }
    }
}

fn main() {
    // Initialize store with default reducer
    let store = Store::<CalcState, CalcAction>::new(Box::new(CalcReducer::default()));

    // Add subscriber
    store.add_subscriber(Arc::new(CalcSubscriber::default()));

    // Dispatch action
    store.dispatch(CalcAction::Add(1));

    thread::sleep(std::time::Duration::from_secs(1));
    // add more subscriber
    store.add_subscriber(Arc::new(CalcSubscriber::default()));

    // Dispatch action
    store.dispatch(CalcAction::Subtract(1));

    // Clean up
    store.stop();
}

Side Effects in Reducers

Unlike traditional Redux implementations, rs-store allows reducers to produce side effects directly. This means reducers can produce asynchronous operations.

This design choice provides more flexibility while maintaining predictable state management.

Notification Channel feature

The notification channel feature provides a dedicated channel for state notifications to subscribers, separating the concerns of state updates and notification delivery. This can help improve performance and reliability by:

  • Decoupling state updates from notification delivery
  • Preventing slow subscribers from blocking state updates
  • Allowing independent backpressure handling for notifications
  • Supporting different threading models for notification delivery

Documentation

For detailed documentation, visit:

Implementation Status

In Progress ๐Ÿšง

  • Latest state notification for new subscribers
  • Notification scheduler (CurrentThread, ThreadPool)
  • Stream-based pull model

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Dependencies

~1.3โ€“2MB
~40K SLoC