npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

reactive-state

v3.7.2

Published

Redux-like state management using RxJS and TypeScript

Downloads

162

Readme

Build Status npm version code coverage

Reactive State

A typed, wrist-friendly state container aimed as an alternative to Redux when using RxJS. Written with RxJS in TypeScript but perfectly usable from plain JavaScript. Originally inspired by the blog posting from Michael Zalecki but heavily modified and extended since.

Features

  • type-safe actions: no boilerplate code, no mandatory string constants, and not a single switch statement
  • Actions are just Observables, so are Subjects. Just call .next() to dispatch an action.
  • dynamically add and remove reducers during runtime
  • no need for async middlewares such as redux-thunk/redux-saga; actions are Observables and can be composed and transformed async using RxJS operators
  • no need for selector libraries like MobX or Reselect, RxJS already ships it
  • single, application-wide Store concept as in Redux. Possibility to create slices/substates for decoupling (easier reducer composition and state separation by module)
  • Strictly typed to find errors during compile time
  • Heavily unit tested, 100+ tests for ~250 lines of code
  • React bridge (like react-redux) included, though using React is not mandatory
  • Support for React-Devtool Extension

Installation

npm install reactive-state

Documentation

Additionally, there is a small example.ts file and see also see the included unit tests as well.

Example Usage

import { Store } from "reactive-state";
import { Subject } from "rxjs";
import { take } from "rxjs/operators";

// The state for our example app
interface AppState {
    counter: number;
}

const initialState: AppState = { counter: 0 }

const store = Store.create(initialState);

// The .watch() function returns an Observable that emits the selected state change, so we can subscribe to it
store.watch().subscribe(newState => console.log("STATE:", JSON.stringify(newState)));

// the watch() observable always caches the last emitted state, so we will immediately print our inital state:
// [CONSOLE.LOG]: STATE: {"counter":0}

// use a RxJS Subjects as an action
const incrementAction = new Subject<number>();

// A reducer is a function that takes a state and an optional payload, and returns a new state
function incrementReducer(state, payload) {
    return { ...state, counter: state.counter + payload };
};

store.addReducer(incrementAction, incrementReducer);

// lets dispatch some actions

incrementAction.next(1);
// [CONSOLE.LOG]: STATE: {"counter":1}
incrementAction.next(1);
// [CONSOLE.LOG]: STATE: {"counter":2}

// async actions? No problem, no need for a "middleware", just use RxJS
interval(1000).pipe(take(3)).subscribe(() => incrementAction.next(1));
// <PAUSE 1sec>
// [CONSOLE.LOG]: STATE: {"counter":3}
// <PAUSE 1sec>
// [CONSOLE.LOG]: STATE: {"counter":4}
// <PAUSE 1sec>
// [CONSOLE.LOG]: STATE: {"counter":5}

License

MIT.