# @ngfk/ng-store

> State management powered by RxJS, enforcing type safety

Latest version **0.0.13** (published 2017-10-02) · MIT license · 0 weekly downloads

## Install

```sh
npm install @ngfk/ng-store
pnpm add @ngfk/ng-store
yarn add @ngfk/ng-store
bun add @ngfk/ng-store
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.13 |
| Published | 2017-10-02 |
| First published | 2017-09-30 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Rick Koster |
| Maintainers | ngfkoster |
| Keywords | rxjs, angular, state, store |

## Links

- npm: https://www.npmjs.com/package/@ngfk/ng-store
- Repository: https://github.com/ngfk/store
- Homepage: https://github.com/ngfk/store#readme
- Issues: https://github.com/ngfk/store/issues
- npm.io page: https://npm.io/package/@ngfk/ng-store

## Alternatives

- [@reckona/mreact-store](https://npm.io/package/@reckona/mreact-store.md) — 976 weekly downloads
- [regular-state](https://npm.io/package/regular-state.md) — 410 weekly downloads
- [@pacote/flux-actions](https://npm.io/package/@pacote/flux-actions.md) — 65 weekly downloads
- [@pilotlab/lux-debug](https://npm.io/package/@pilotlab/lux-debug.md) — 39 weekly downloads
- [vue-persist-state](https://npm.io/package/vue-persist-state.md) — 19 weekly downloads

## Recent versions

- 0.0.13 (latest) — 2017-10-02
- 0.0.12 — 2017-10-02
- 0.0.11 — 2017-10-02
- 0.0.10 — 2017-10-02
- 0.0.9 — 2017-10-02
- 0.0.8 — 2017-10-01
- 0.0.7 — 2017-10-01
- 0.0.6 — 2017-10-01
- 0.0.5 — 2017-10-01
- 0.0.4 — 2017-10-01
- 0.0.3 — 2017-10-01
- 0.0.2 — 2017-09-30
- 0.0.1 — 2017-09-30

## README

# @ngfk/ng-store

State management powered by [RxJS](https://github.com/ReactiveX/rxjs) enforcing type safety, inspired by [`@ngrx/store`](https://github.com/ngrx/platform) and [`Redux`](http://redux.js.org). Creating reducers and dispatching actions will be type safe.

[![npm version](https://img.shields.io/npm/v/@ngfk/ng-store.svg)](https://www.npmjs.com/package/@ngfk/ng-store)

## Setup

[TLDR](examples/ng-store)
1. Define state structure
2. Map actions
3. Create reducers
4. Create store

### 1. Define state structure

```typescript
interface Todo {
    readonly id: number;
    readonly text: string;
    readonly completed: boolean;
}

enum Filter {
    All,
    Completed,
    Active
}

interface State {
    readonly todos: Todo[];
    readonly filter: Filter;
}
```

### 2. Map actions

```typescript
interface TodoActionMap {
    TODO_ADD: { id: number; text: string };
    TODO_TOGGLE: number;
    TODO_REMOVE: number;
}

interface FilterActionMap {
    FILTER_SET: Filter;
}

interface ActionMap extends TodoActionMap, FilterActionMap {}
```

### 3. Create reducers

```typescript
const todosReducer = createReducer<Todo[], TodoActionMap>([], {
    TODO_ADD: (state, payload) => [
        ...state,
        { id: payload.id, text: payload.text, completed: false }
    ],
    TODO_TOGGLE: (state, payload) => {
        return state.map(
            todo =>
                todo.id === payload
                    ? { ...todo, completed: !todo.completed }
                    : todo
        );
    },
    TODO_REMOVE: (state, payload) => {
        return state.filter(todo => todo.id !== payload);
    }
});

const filterReducer = createReducer<Filter, FilterActionMap>(Filter.All, {
    FILTER_SET: (_, payload) => payload
});

const reducer = combineReducers<State>({
    todos: todosReducer,
    filter: filterReducer
});
```

### 4. Create store service & provide it

```typescript
import { Injectable } from '@angular/core';
import { Store } from '@ngfk/store';

import { ActionMap, reducer, State } from '../state';

@Injectable()
export class StoreService extends Store<State, ActionMap> {
    constructor() {
        super(reducer);
    }
}
```

```typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgStoreModule } from '@ngfk/ng-store';

@NgModule({
    declarations: [AppComponent],
    imports: [
        BrowserModule,
        NgStoreModule.forRoot({
            store: StoreService
        })
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule {}
```

## Example Usage
```typescript
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';

@Component({
    selector: 'app-root',
    template: `
        <div>
            <button (click)="dispatch()">dispatch</button>
            <button (click)="clear()">clear</button>
            <hr>
            <p>State:</p>
            <pre>{{todos$ | async | json}}</pre>
        </div>
    `
})
export class AppComponent {
    public todos$: Observable<Todo[]>;

    constructor(private store: StoreService) {
        this.todos$ = this.store.select(state => state.todos);
    }

    public dispatch(): void {
        this.store.dispatch('TODO_ADD', 'Dispatched TODO!');
    }

    public clear(): void {
        this.store.reset();
    }
}
```

---
_Source: https://npm.io/package/@ngfk/ng-store · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
