@recubed/storx
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

MIT license Build Status Coverage Status CodeFactor dependencies Status devDependencies Status

Storx

RxJS-based state management. Borrows concepts from Redux, Effector and few others but targets minimalism and strong RxJS reliance rather than custom internals.

This is a revamped version of Storx. Differs from its predecessor in both implementation and dsl but persists the core ideas of simplicity and RxJS dependency.

Core artifacts

  • Store (known events[]) - an object that relies on variable-size set of events (provided via constructor function) that it then triggers when dispatch is called. Stores the state object and - depending on an event type definition (effectful or effectless) - may also perform updates.

  • Events (effectful | effectless) - tuples of Subject and nullable transformation function, discriminated with kind property. Created via 2-ary constructor function that allows strict, granular control over the transformation function definition.

  • Effects - given Store and Event(s) references Effect will listen on event emissions and trigger side effects. If a tuple of event and transformation function is provided as a 2-nd argument effect will also run the transformation on source event payload and dispatch the result to the target event stream (second element of the aforementioned tuple).

  • Selectors - Store projections created with custom RxJS select operator. Selectors are memoized, values are compared using deep-is algorithm.

Installation

npm i @recubed/storx

or

yarn add @recubed/storx

API

  • Store creation
import { Store, EventStream, Effect, select } from '@recubed/storx';
import { skip } from 'rxjs/operators';

const eventStream = EventStream('some-event');
const otherEventStream = EventStream('other-event');

const store = Store({ prop: 42 }, eventStream, otherEventStream);
  • Dispatching events
store.allEvents.subscribe(ev => {
  console.log(ev);
  // { kind: 'some-event',  status: 'successful' }
});

store.dispatch(eventStream);
  • Dispatching state updates
const effectfulEventStream = EventStream('update-prop', {
  //where to find state slice to transform
  select: state => state.prop,
  //how to update the state
  write: (state, patch) => ({ ...state, prop: patch }),
  //how to transform previous value
  xf: (value, patch) => value + patch
});

store.state.subscribe(state => {
  console.log(state.prop);
  // 50
});

store.dispatch(effectfulEventStream, 8);
  • Reading current state
console.log(store.valueOf());
// { prop: 50 }
  • Reading current state and last update-causing event
import { withReason } from '@tanfonto/storx';

withReason(store).subscribe([ state, event ] => {
  console.log(state, event);
  // { prop: 50 } { kind: 'update-prop',  status: 'successful', patch: 8 }
}) 
  • Effects creation
const makeEffect = Effect(store);
makeEffect(eventStream, (state, patch) => {
  console.log(state, patch);
  // { prop: 50 } 42
});

store.dispatch(eventStream, 42);
  • Chained Effects creation
const makeEffect = Effect(store);
makeEffect(eventStream, [otherEventStream, (_state, patch) => patch]);

store.allEvents.pipe(skip(1)).subscribe(ev => {
  console.log(ev);
  // { kind: 'other-event', status: 'successful', patch: 42 }
});

store.dispatch(eventStream, 42);
  • Selectors (select operator)
  store.state.pipe(select(x => x.prop))
    .subscribe(x => {
      console.log(x)
      //42, 9001 [selectors are memoized therefore second dispatch will not emit] 
    });

  store.dispatch(eventStream, 42);
  store.dispatch(eventStream, 42);
  store.dispatch(eventStream, 9001);
});

store.dispatch(eventStream, 42);

Examples

License

MIT

Package Sidebar

Install

npm i @recubed/storx

Weekly Downloads

1

Version

1.0.0

License

MIT

Unpacked Size

12.3 kB

Total Files

12

Last publish

Collaborators

  • tanfonto