createStore
Overview
Section titled “Overview”createStore creates a BehaviorSubject-based reactive state container. It provides a familiar get/set API while exposing the current state as an Observable stream. Selectors derived via select() emit only when the selected slice actually changes, keeping downstream subscribers efficient.
Import
Section titled “Import”import { createStore } from "rxjs-ai";Basic usage
Section titled “Basic usage”import { createStore } from "rxjs-ai";
interface CounterState { count: number; label: string;}
const store = createStore<CounterState>({ count: 0, label: "My Counter",});
// Subscribe to the full state streamstore.state$.subscribe((state) => { console.log("State changed:", state);});
// Read synchronouslyconsole.log(store.getState().count); // 0
// Derive a selector – only emits when `count` changesconst count$ = store.select((s) => s.count);count$.subscribe((count) => console.log("count:", count));
// Patch a partial updatestore.patchState({ count: 1 });
// Replace the entire state with a function-based updaterstore.setState((prev) => ({ ...prev, count: prev.count + 1 }));
// Clean up when donestore.destroy();| Member | Signature | Description |
|---|---|---|
state$ | Observable<State> | Emits the full state object on every change. Replays the current value to new subscribers. |
getState() | () => State | Returns a synchronous snapshot of the current state. |
setState(updater) | (updater: State | StateUpdater<State>) => void | Replaces the entire state. Accepts a new state object or a callback that receives the previous state and returns the next state. |
patchState(patch) | (patch: StatePatch<State>) => void | Shallow-merges a partial object into the current state. Accepts a partial object or a function that receives the previous state and returns a partial object. |
select(selector, compare?) | <R>(selector: (state: State) => R, compare?: (a: R, b: R) => boolean) => Observable<R> | Derives a projected Observable from the state. Uses distinctUntilChanged so subscribers only receive emissions when the selected value changes. |
destroy() | () => void | Completes the internal BehaviorSubject and all derived selectors. |
Advanced
Section titled “Advanced”Custom comparator for select
Section titled “Custom comparator for select”By default, select uses referential equality (===) to determine whether the derived value has changed. You can supply a custom comparator for deep or structural equality checks:
import { isEqual } from "lodash-es";
const todos$ = store.select((s) => s.todos, isEqual);This is especially useful when the selector returns a new array or object reference on every emission but the contents remain the same.
Function-based updaters
Section titled “Function-based updaters”setState accepts either a plain state object or an updater function. Updater functions are the safest choice when the next state depends on the previous state:
// Plain object – replaces the entire statestore.setState({ count: 10, label: "Reset" });
// Updater function – derives next state from previousstore.setState((prev) => ({ ...prev, count: prev.count + 1,}));/** The store instance returned by createStore. */type Store<State> = { state$: Observable<State>; getState: () => State; setState: (updater: State | StateUpdater<State>) => void; patchState: (patch: StatePatch<State>) => void; select: <R>( selector: (state: State) => R, compare?: (a: R, b: R) => boolean, ) => Observable<R>; destroy: () => void;};
/** A callback that receives the current state and returns the next state. */type StateUpdater<State> = (current: State) => State;
/** A partial representation of the state used by patchState. Accepts a partial object or a function that returns one. */type StatePatch<State extends object> = | Partial<State> | ((previousState: State) => Partial<State>);