🍃 Lightweight and dependency-free
🔀 Supports both immutable (setState)
and mutable (updateState)
updates
🔍 Supports custom selectors
, actions
, and transformers
🧪 Built with TypeScript in mind, providing robust type safety and inference
⚡️ React 18+ concurrent rendering safe
npm install avastha
# or
yarn add avastha
import { create } from "avastha";
const counterStore = create(({ setState }) => ({
state: { count: 0 },
actions: {
increment: () => setState((s) => ({ count: s.count + 1 })),
decrement: () => setState((s) => ({ count: s.count - 1 })),
},
}));
function Counter() {
const count = counterStore.useState((s) => s.count);
const increment = counterStore.useAction((a) => a.increment);
const decrement = counterStore.useAction((a) => a.decrement);
return (
<>
<p>{count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</>
);
}
const fruitStore = create(({ updateState }) => ({
state: { fruits: [] },
actions: {
addFruit: (name) => updateState((s) => s.fruits.push(name)),
},
}));
If your store has a transforms object, Avastha will check if your selector returns a transformer function and apply it to the selection.
const userStore = create(({ setState }) => ({
state: { firstName: "Ada", lastName: "Lovelace" },
transforms: {
fullName: ({ firstName, lastName }) => `${firstName} ${lastName}`,
},
}));
const fullName = userStore.useState((s) => s.fullName); // "Ada Lovelace"
create(initializer, debugFn?)
Returns an object with useState and useAction.
useState(selector)
Subscribes to a derived slice of state using a selector function.
useAction(selector)
Accesses a specific action via a selector function.
Pass a debugFn to create
to observe state changes:
const debugFn = (next, prev, updated) => {
console.log("State changed:", { prev, updated, next });
};
const store = create(initializer, debugFn);
You can explore more usage examples in the examples/avastha-example
directory:
- Basic counter
- Nested state
- Nested state with Transforms
- Multiple slices