@rx-signals/store
Reactive state and effects management
:warning: This documentation is work in progress for the upcoming 3.0.0 version.
There is however no good reason to use 2.7 over 3.0.0-rc6, so please start with the rc-version.
3.0.0-rc6 is better than 2.7 in any aspect and the code is production-ready.
It is now more or less documentation that needs improvement (though 2.7 had nearly no documentation at all).
It is however possible that I will introduce minor breaking changes until 3.0.0 is released.
3.0.0 will also be the first version I'm going to advertise to other people (so if you're reading this, you likely reached this site by google-accident or something like that).
Installation
npm install --save @rx-signals/store@3.0.0-rc6
Dependencies
RxJs is the one and only peer dependency. You need a version >6.4.0 (so 7.x is also perfectly fine) in your project.
License
MIT
What is it?
rx-signals is a library for the MVU (Model-View-Update) pattern.
It is however not limited to MVU, but can be used in all architectures that would benefit from its features:
- State Management
- Reactive Programming
- High-level abstractions over RxJs (you can still go as low as you want)
- Effects Management
- Clean side-effect isolation
- Mock-less testing of your application logic
- An alternative to Redux, NgRx or other MVU-libs
- Less boilerplate / More DRY
- More abstractions / Better reusability
Though it heavily relies on RxJs, this lib is not Angular-specific. You can (and should) also use it in any other context where you have RxJs at your disposal!
(Use it in the backend or with any presentation-framework you like. Decoupling all application-logic from presentation-logic is a strength of this library.)
rx-signals itself is implemented with TypeScript and therefore naturally comes fully typed (in case you're using it with TS).
High-level overview
This lib comes with a
- Store for
- State-management based on the RP (reactive programming) concepts of events and behaviors (generalized as signals)
- Reactive dependency injection
- Signals- and SignalsBuilder Types as
- Encapsulation/Abstraction-layer over low-level signal-composition
- SignalsFactory as
- Abstraction-layer over the SignalsBuilder-Type for high-level composition and reusability (enabling DRY architecture)
- EffectSignalsFactory as
- SignalsFactory that covers all side-effect-scenarios generically, encapsulating and abstracting away all the pitfalls and possibilities to shoot yourself in the foot.
Getting started
The impatient reader may skip the terminology part and head on to Directions.
Terminology
What does rx-signals mean anyway?
Well the rx stands for reactive extensions, so it's the same rx as in RxJs.
The term signals is lent from the world of functional reactive programming (FRP), though rx-signals features reactive programming (RP).
You can skip to the definition of signals in RP, if you're not really interested in the actual difference between FRP and RP:
In FRP, there are two kinds of signals:
- Events:
- Signals of values that occur at discrete points in time
- So functions of time that may or may not yield a value
- An event can depend on several conditions (e.g. other signals)
- Behaviors:
- Signals of dynamic values over continuous time
- So functions of time that alwayas yield a value
- A behavior can depend on other behaviors and/or events
The FRP-guys may pardon me for having over-simplified a bit.
If you're interested in an exact definition, here you can start (though the above definition better resembles RT-FRP, so the original paper is really just a start).
We're however not interested in the continuous world of FRP, but instead we're working with programs that change in discrete steps, which brings us to RP (in RP the signals are not functions of time, but only of ordered signals they depend on).
This is really confusing, because actually in RP, we're making use of functional programming a lot!
It's just that the term FRP is reserved for the thing where behaviors are real functions of continous time.
Don't worry, if this is confusing or even if you still have no idea what I'm talking about.
At least if you're already familiar with RxJs (which is a RP-library), it's going to become much more clear next.
The FRP-definitions of events and behaviors translate to the following definitions for RP:
- Event-streams:
- Value-streams that have no current value
- Publish values (events) to subscribers at discrete points of time
- Can depend on other event-streams and/or behaviors
- Behaviors:
- Value-Streams that always have a current value (though possibly lazy)
- Current value can change at discrete points in time (published to subscribers)
- Can depend on other behaviors and/or event-streams
So an RxJs example for behaviors would be a BehaviorSubject, while an example for event-streams would be Subjects.
Thus, in RxJs-world you can translate signal as observable. (Now that we arrived at RxJs terminology: another difference between FRP and RP is that in RP, a signal can simply end, hence observables can complete.)
Directions
You should start with my introduction to MVU, State Management, Reactive Programming and Effects Management, if
- you don't know what any of these terms mean
- you like to understand the basis for the rx-signals architecture
- you think State Management is only about having a global state and how to modify it
- you think you're doing RP, just because you're using something like RxJs
- you think Effects Management is only about managing async processes (like http calls)
- you don't know that all these things are tied together
Otherwise, you may start with Using rx-signals.
Where necessary, it will still link to the corresponding passages of the formerly mentioned introduction.
The API-documentation (as generated from the doc strings) can be found here
An introduction for people with NgRx background can be found here