Module @watchable/store

A minimal pattern for watchable state

513 gzipped bytes of powerful state-management!

A Store maintains a protected reference to an array or object state that is treated as immutable. When a new state is passed to store.write(), user interfaces and business logic are notified of changes to state matching their Selectors.

@watchable/store is incredibly simple, lightweight and framework-independent, and therefore suited to manage state within almost any server-side or client-side Typescript or Javascript project.

Read the API Reference, examine the example code below, or browse the source on Github. There is also a Medium article describing the approach

Usage

Create a Store - Javascript

const store = createStore({ counter: 0 });

Create a Store - Typescript

import { createStore, type Immutable} from "@watchable/store"

// `Immutable` blocks inadvertent state edits - recommended but optional.
type CounterState = Immutable<{
counter: number;
}>

const INITIAL_STATE : CounterState = {
counter: 0,
} as const;

const store = createStore(INITIAL_STATE);

Read and Write State

// read state
const state = store.read();

// write state using immutable patterns
store.write({
...state,
counter: state.counter + 1,
});

// create the next immutable state by
// editing a draft (backed by Immer)
import { edit } from "@watchable/store-edit";
edit(store, (draft) => (draft.counter += 1));

Track State

/* REACT-BASED */

// using selector and memoized Hook (React framework)
// re-renders after the selected value changes
import { useSelected } from "@watchable/store-react";
const counter = useSelected(store, (state) => state.counter);

// get and set keyed property, (like React useState), with intellisense for valid keys
const [counter, setCounter] = useStateProperty(store, "counter");

/* FRAMEWORK AGNOSTIC */

// using a watcher
store.watch((state) => console.log(`Counter is ${state.counter}`));

// using selector and memoized callback (Framework independent)
// invoked each time the selected value changes
import { followSelector } from "@watchable/store-follow";
followSelector(
store,
(state) => state.counter,
(counter) => {
console.log(`Counter is ${counter}`);
}
);

Import OR Require

import { createStore } from "@watchable/store"; // gets esm build
const { createStore } = require("@watchable/store"); // gets commonjs build

Getting Started

Install

npm install @watchable/store

Demonstration Apps

The Example Counter Apps offer minimal demonstrations of @watchable/store

Index

Interfaces

Type Aliases

Functions