UNPKG

@platform/state

Version:

A small, simple, strongly typed, [rx/observable] state-machine.

48 lines (47 loc) 1.62 kB
import { takeUntil } from 'rxjs/operators'; import { is } from '../common'; export function create(factory) { return (initial, dispose$) => { const initialStateObjects = []; initial = Object.keys(initial).reduce((acc, key) => { const value = initial[key]; if (is.stateObject(value)) { acc[key] = value.state; initialStateObjects.push({ key, obj: value }); } else { acc[key] = value; } return acc; }, {}); const store = factory(initial); if (dispose$) { dispose$.subscribe(() => api.dispose()); } const change = (key, to) => store.change((draft) => (draft[key] = to)); const api = { store, get state() { return store.state; }, get changed$() { return store.event.changed$; }, add(key, subject) { const isObservable = is.observable(subject); const changed$ = isObservable ? subject : subject.event.changed$; if (!isObservable) { const obj = subject; change(key, obj.state); } changed$.pipe(takeUntil(store.dispose$)).subscribe((e) => change(key, e.to)); return api; }, dispose: () => store.dispose(), }; initialStateObjects.forEach(({ key, obj }) => api.add(key, obj)); return api; }; }