Skip to content

ilokesto/store

Repository files navigation

@ilokesto/store

English | 한국어

A small and simple TypeScript Store class.

This package serves as a vanilla store core for building React state management libraries. It provides state storage, updates, and subscription features without any React dependencies.

Features

  • Generic-based Store<T>
  • Get current state: getState()
  • Get initial state: getInitialState()
  • Update state with value or updater function: setState()
  • Register middleware: setMiddleware()
  • Subscribe / Unsubscribe: subscribe()
  • Skips notifications when updated with the same reference
  • Safely iterates listeners even if unsubscriptions occur during notification

Installation

pnpm add @ilokesto/store

or

npm install @ilokesto/store

Basic Usage

import { Store } from "@ilokesto/store";

type CounterState = {
  count: number;
};

const counterStore = new Store<CounterState>({ count: 0 });

const unsubscribe = counterStore.subscribe(() => {
  console.log("changed:", counterStore.getState());
});

counterStore.setState({ count: 1 });
counterStore.setState((prev) => ({ count: prev.count + 1 }));

console.log(counterStore.getInitialState());
console.log(counterStore.getState());

unsubscribe();

API

new Store<T>(initialState: T)

Creates a Store instance with the initial state.

const store = new Store({ count: 0 });

store.getState(): Readonly<T>

Returns a snapshot of the current state.

const state = store.getState();

store.getInitialState(): Readonly<T>

Returns the initial state provided when the Store was created.

const initialState = store.getInitialState();

store.setState(nextState: SetStateAction<T>): void

Replaces the state with a new value or computes the next state based on the previous one.

store.setState({ count: 10 });

store.setState((prev) => ({
  count: prev.count + 1,
}));

It does not notify subscribers if Object.is(prevState, nextState) is true.

Functions passed to setState() are always treated as updaters. As a result, the current API is not suitable for patterns where the state value itself is a function.

store.setMiddleware(middleware: (nextState: SetStateAction<T>, next: Dispatch<SetStateAction<T>>) => void): void

Adds a middleware to the store. Middlewares wrap the setState operation and run in the order they were registered.

store.setMiddleware((nextState, next) => {
  console.log("Before update:", nextState);
  next(nextState);
  console.log("After update");
});

A middleware receives the nextState: SetStateAction<T> and a next: Dispatch<SetStateAction<T>> function to continue the chain. The first middleware you register becomes the outermost wrapper, so a before -> next -> after pattern runs like nested function calls around the final state application. The final next call applies the state and notifies subscribers.

store.subscribe(listener: () => void): () => void

Registers a listener to be executed when the state changes. Returns an unsubscribe function.

const unsubscribe = store.subscribe(() => {
  console.log("state changed");
});

unsubscribe();

State Semantics

This Store treats state as immutable snapshots.

  • Always update state via setState() instead of modifying it directly.
  • Update object or array states by returning a new reference.
  • Providing the same reference will not be considered a change.

Recommended:

store.setState((prev) => ({
  ...prev,
  count: prev.count + 1,
}));

Not recommended:

store.setState((prev) => {
  prev.count += 1;
  return prev;
});

Current Scope

This package currently handles only the following:

  • State storage
  • State replacement
  • Subscription management
  • Middleware support

It does not yet include:

  • React hooks
  • Selector / equality helpers
  • DevTools integration
  • Persistence helpers

This package is a minimal core rather than a full featured React state management library.

Development

pnpm install
pnpm run build

Build outputs are generated in the dist directory.

License

MIT

About

A small and simple TypeScript Store class.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors