rxfeedback
v4.0.0
Published
Architecture for RxJS
Maintainers
Readme
RxFeedback
TypeScript/JavaScript version of RxFeedback
The simplest architecture for RxJS
type FeedbackLoop<State, Event> =
(state: rx.Observable<State>) => rx.Observable<Event>;
type ErrorHandling<State, Event> = {
// Calculates the new state in case `reduce` throws. Rethrowing terminates the system.
onReduceError: (state: State, error: any) => State;
// Applied to the events of every single feedback loop.
feedbackErrorGuard: (events: rx.Observable<Event>) => rx.Observable<Event>;
};
function system<State, Event>(
initialState: State,
reduce: (state: State, event: Event) => State,
feedback: FeedbackLoop<State, Event>[],
// defaults to `rx.queueScheduler`
scheduler?: SchedulerLike,
// defaults to `defaultErrorHandling()`: `reduce` errors are logged to the console
// and the last good state is kept, feedback loops are retried by using the
// `defaultRetryStrategy` (exponential backoff, at most 5 seconds between the retries)
errorHandling?: ErrorHandling<State, Event>
): rx.Observable<State>;Why
Straightforward
- If it did happen -> Event
- If it should happen -> Request
- To fulfill Request -> Feedback loo
Declarative
- System behavior is first declaratively specified and effects begin after subscribe is called => Compile time proof there are no "unhandled states"
Debugging is easier
- A lot of logic is just normal pure function that can be debugged using Xcode debugger, or just printing the commands.
Can be applied on any level
- Entire system
- application (state is stored inside a database, CoreData, Firebase, Realm)
- view controller (state is stored inside
systemoperator) - inside feedback loop (another
systemoperator inside feedback loop)
Works awesome with dependency injection
Testing
- Reducer is a pure function, just call it and assert results
- In case effects are being tested -> TestScheduler
Can model circular dependencies
Completely separates business logic from effects (Rx).
- Business logic can be transpiled between platforms
Installing with NPM
$ npm install rxfeedbackimport * as RxFeedback from 'rxfeedback';