5.1.0 • Published 11 months ago

mini-rx-store v5.1.0

Weekly downloads
12
License
MIT
Repository
github
Last release
11 months ago

MiniRx: The Lightweight RxJS Redux Store

MiniRx Store provides Reactive State Management for Javascript Applications.

Features

  • Minimal configuration and setup
  • Simplified API for basic state management per feature:
    • setState() for updating the feature state,
    • $state for accessing the current feature state
  • Advanced "Redux / NgRX" API: Although being a lightweight library, MiniRX supports many of the core features from the popular NgRX library for Angular: Actions Reducers Memoized Selectors Effects
  • MiniRX is lightweight - check the source code :)
  • The source code is easy to understand if you know some RxJS :)
  • RxJS is the one and only (peer) dependency
  • Framework agnostic

Usage (in Angular)

Create the MiniStore (App State):

The MiniStore is created as soon as you import MiniStore.

import { MiniStore } from 'mini-rx-store';

Create a MiniFeature (Feature State):

A MiniFeature holds a piece of state which belongs to a specific feature in your application (e.g. 'products', 'users'). The Feature States live inside the AppState.

import { MiniStore } from 'mini-rx-store';
import { initialState, ProductState, reducer } from './state/product.reducer';
...
export class ProductStoreService {
    constructor() {
      MiniStore.feature<ProductState>('products', initialState, reducer);
    }
}

The code above creates a new feature state for products. Its initial state is set and the reducer function defines how the feature state changes with an incoming Action.

A reducer function typically looks like this:

export function reducer(state: ProductState, action: ProductActions): ProductState {
  switch (action.type) {
    case ProductActionTypes.ToggleProductCode:
      return {
        ...state,
        showProductCode: action.payload
      };

    default:
      return state;
  }
}

Usually you would create a new MiniFeature inside long living Modules/Services.

Write an effect:

Effects handle code that triggers side effects like API calls.

import { Action, actions$, ofType } from 'mini-rx-store';
import { LoadFail, LoadSuccess, ProductActionTypes } from './product.actions';

private loadProducts$: Observable<Action> = actions$.pipe(
    ofType(ProductActionTypes.Load),
    mergeMap(action =>
      this.productService.getProducts().pipe(
        map(products => (new LoadSuccess(products))),
        catchError(err => of(new LoadFail(err)))
      )
    )
);

The code above creates an Effect. As soon as the Load Action is dispatched the API call (this.productService.getProducts()) will be executed. Depending on the result of the API call a new Action will be dispatched: LoadSuccess or LoadFail.

You need to register the effect before it can take action... (see next section).

Register one or many effects:

MiniStore.effects([loadProducts$]);

Dispatch an Action:

import { MiniStore } from 'mini-rx-store';
import { CreateProduct } from 'product.actions';

MiniStore.dispatch(new CreateProduct(product));

Create Selectors:

Selectors are used to select and combine state.

import { createFeatureSelector, createSelector } from 'mini-rx-store';

const getProductFeatureState = createFeatureSelector('products');

export const getProducts = createSelector(
    getProductFeatureState,
    state => state.products
);

Select Observable State (with a selector):

import { MiniStore } from 'mini-rx-store';
import { getProducts } from '../../state';

this.products$ = MiniStore.select(getProducts);

Make simple things simple:

If a Feature in your application requires only simple state management, then you can fall back to a simplified API which is offered for each MiniFeature instance (returned by MiniStore.feature())

private feature: MiniFeature<UserState> = MiniStore.feature<UserState>('users', initialState);

// get state via the state$ Observable
// use th RxJS map operator to get a specific piece of the feature state
maskUserName$: Observable<boolean> = this.feature.state$.pipe(map(state => state.maskUserName));

updateMaskUserName(maskUserName: boolean) {
    // Update State
    this.feature.setState((currState) => {
        return {
            ...currState,
            maskUserName
        }
    });
}

state$ is an Observable which will emit the current state of the feature.

setState takes a function which specifies how the feature state is supposed to be updated. That function has access to the current state of the feature (see currState parameter).

Behind the scenes the MiniFeature creates a default reducer and a default action. When you use setState() then the default action is dispatched the default reducer will update the feature state for you.

Enable Logging of Actions and State Changes in the Browser Console:

import { MiniStoreSettings } from 'mini-rx-store';

MiniStoreSettings.enableLogging = true;

The code above adjusts the Global MiniStore Settings. Typically you would set the settings when bootstrapping the app and before the store is used.

TODO

  • Integrate Redux Dev Tools
  • Work on the ReadMe and Documentation
  • Nice To Have: Test lib in React, Vue, maybe even AngularJS
  • Add Unit Tests
  • Expose NgModule for easier Angular Integration
  • Publish lib to npm
5.1.0

11 months ago

5.0.0-rc.0

1 year ago

5.0.1

1 year ago

5.0.0

1 year ago

5.0.0-alpha.3

1 year ago

5.0.0-alpha.2

1 year ago

5.0.0-alpha.1

1 year ago

5.0.0-alpha.0

1 year ago

4.0.0

2 years ago

4.2.0

1 year ago

4.1.0

1 year ago

4.0.0-rc.1

2 years ago

4.0.0-rc.0

2 years ago

4.0.0-beta.3

2 years ago

4.0.0-beta.2

2 years ago

4.0.0-beta.1

2 years ago

4.0.0-alpha.9

2 years ago

4.0.0-alpha.7

2 years ago

4.0.0-alpha.8

2 years ago

4.0.0-alpha.14

2 years ago

4.0.0-alpha.13

2 years ago

4.0.0-alpha.12

2 years ago

4.0.0-alpha.11

2 years ago

4.0.0-alpha.10

2 years ago

4.0.0-beta.0

2 years ago

4.0.0-alpha.5

2 years ago

4.0.0-alpha.6

2 years ago

4.0.0-alpha.3

2 years ago

4.0.0-alpha.4

2 years ago

4.0.0-alpha.1

2 years ago

4.0.0-alpha.2

2 years ago

4.0.0-alpha.0

2 years ago

3.1.0

2 years ago

3.0.1

2 years ago

3.0.0

3 years ago

3.0.0-rc.2

3 years ago

3.0.0-rc.1

3 years ago

3.0.0-rc.0

3 years ago

3.0.0-beta.3

3 years ago

3.0.0-beta.1

3 years ago

3.0.0-beta.0

3 years ago

3.0.0-beta.2

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

2.0.0-beta.4

3 years ago

2.0.0-beta.3

3 years ago

2.0.0-beta.2

3 years ago

2.0.0-beta.1

3 years ago

2.0.0-beta.0

3 years ago

1.0.1

4 years ago

1.0.0

4 years ago

1.0.0-rc.2

4 years ago

1.0.0-rc.1

4 years ago

1.0.0-rc.0

4 years ago

1.0.0-beta.13

4 years ago

1.0.0-beta.12

4 years ago

1.0.0-beta.11

4 years ago

1.0.0-beta.10

4 years ago

1.0.0-beta.9

4 years ago

1.0.0-beta.8

4 years ago

1.0.0-beta.7

4 years ago

1.0.0-beta.6

4 years ago

1.0.0-beta.3

4 years ago

1.0.0-beta.4

4 years ago

1.0.0-beta.5

4 years ago

1.0.0-beta.2

4 years ago

1.0.0-beta.1

4 years ago

1.0.0-beta.0

4 years ago