Skip to content

lacolaco/reactive-store

Repository files navigation

@lacolaco/reactive-store

Very simple store implementation for state management with RxJS.

https://yarn.pm/@lacolaco/reactive-store

CI

npm version

Install

$ yarn add rxjs @lacolaco/reactive-store

Concept

  • RxJS: Use the ecosystem
  • TypeScript: Type-safe state management
  • Simple: Easy to understand what the library does and doesn't

How to Use

Create a store: new Store({ initialValue })

import { Store } from '@lacolaco/reactive-store';

export interface CounterState {
  count: number;
}

export const initialValue: CounterState = {
  count: 0,
};

export const counterStore = new Store<CounterState>({ initialValue });

Use the store

Get the current value: .value: T

export const counterStore = new Store<CounterState>({ initialValue: 1 });

console.log(counterStore.value); // => 1

Observe value changes: .valueChanges: Observable<T>

.valueChange returns a raw observable of the store.

export const counterStore = new Store<CounterState>({ initialValue: 1 });

counterStore.valueChanges.subscribe((value) => {
  console.log(value); // => 1
});

// You can use `pipe` and operators of RxJS.
const doubled$: Observable<number> = counterStore.valueChanges.pipe(map((value) => value * 2));

Update the store: .update((value: T) => T): void

update takes a function which takes the current value and returns a new value.

export const counterStore = new Store<CounterState>({ initialValue: 1 });

counterStore.update((value) => value + 1);

console.log(counterStore.value); // => 2

Observe scoped value: .select((value: T) => U): Observable<U>

select method is for mapping and memoize the scoped value. This is using internally it uses RxJS's map and distinctUntilChanged operators.

export const counterStore = new Store<CounterState>({
  initialValue: { count: 1 },
});

counterStore.valueChanges.subscribe((value) => {
  console.log(value); // => { count: 1 }
});

const selected$: Observable<number> = counterStore.select((value) => value.count);

selected$.subscribe((value) => {
  console.log(value); // => 1
});

Listen update events: .storeUpdateChanges: Observable<StoreUpdateChange<T>>

A store dispatchs a change event every time updating the store. This is for debugging or integrating with other tools.

const counterStore = new Store<CounterState>({
  initialValue,
});

counterStore.storeUpdateChanges.subscribe((change) => {
  console.log(`Previous Value`, change.previousValue);
  console.log(`Current Value`, change.currentValue);
  console.log(`Label`, change.label);
});

label is a string value you can pass to update as an option.

export const counterStore = new Store<CounterState>({ initialValue: 1 });

counterStore.update((value) => value + 1, { label: 'increment' });

Reset the store: .reset(): void

reset the store with the initial value.

export const counterStore = new Store<CounterState>({ initialValue: 1 });

counterStore.reset();

License

MIT

Author

Suguru Inatomi a.k.a. @lacolaco