nsrx
TypeScript icon, indicating that this package has built-in type declarations

1.0.6 • Public • Published

nsrx (not so redux)

I don't like existing Redux libraries so I just create my own. The goal is to use Redux with minimal boilerplate and in a natural way.

To start

  1. Create a class extending NxrsState<StateModel>.
  2. Call the super constructor with the path name you want.
  3. Use state$ to select the state.
    1. Or create your own selector with this.state$.pipe(...).
    2. Add distinctUntilChanged() so it only publish changed value.
    3. Add shareReplay(1) so the value get cached for multiple subscriber.
  4. Add action by using this.reducer<Payload>(action, callback).
    1. callback accepts parameter state, setState and payload.
    2. It must use setState to modify the state before return.
  5. If you want to use it in Angular, just annotate it with @Injectable() (https://angular.io/guide/dependency-injection).

Simple Example

class CounterState extends NsrxState<{ value: number }>  {
    public readonly value$ = this.memoize(this.state$.pipe(map(s => s.value)));

    public readonly increase = this.reducer<{ amount: number }>('Increase',
        (state, setState, payload) => setState({ value: (state?.value || 0) + payload.amount }));

    constructor() {
        super('counter');
    }
}

counterState.increase({ amount: 10 });

Example with side effects

class CounterState extends NsrxState<CounterStateModel>{
    readonly value$ = this.memoize(this.state$.pipe(map(s => s.value)));
    readonly autoIncreaseIsEnabled$ = this.memoize(this.state$.pipe(map(s => s.autoIncreaseIsEnabled)));

    readonly init = this.reducer(
        `Init counter ${this.name}`,
        (_, setState) => setState({ autoIncreaseIsEnabled: false, value: 0 })
    );

    readonly increase = this.reducer<{ value: number }>(
        `Increase counter ${this.name}`,
        (state, setState, payload) => setState({ ...state, value: state.value + payload.value })
    );

    readonly enableAutoIncrease = this.reducer<{ isEnabled: boolean }>(
        `Enable auto increase counter ${this.name}`,
        (state, setState, payload) => {
            const newState = setState({ ...state, autoIncreaseIsEnabled: payload.isEnabled });

            this.subscription?.unsubscribe();
            if (newState.autoIncreaseIsEnabled) {
                this.subscription = interval(1000).subscribe(() => this.increase({ value: 1 }));
            }
        }
    )

    private subscription: Subscription;

    constructor(public readonly name: string) {
        super(`counter_${name}`);
        this.init();
    }
}

Use it with Redux tools

NsrxState.attach(nsrxDevTools);

Log all state changes to console

NsrxState.attach(nsrxLogger);

Readme

Keywords

Package Sidebar

Install

npm i nsrx

Weekly Downloads

0

Version

1.0.6

License

MIT

Unpacked Size

1.45 MB

Total Files

20

Last publish

Collaborators

  • chimin