Product
Socket Now Supports uv.lock Files
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
💥 ⭐️ 💥 ✨
✨ ✨
███████╗████████╗ █████╗ ████████╗███████╗██████╗ ██╗ ██╗██╗ ✨
██╔════╝╚══██╔══╝██╔══██╗╚══██╔══╝██╔════╝██╔══██╗╚██╗ ██╔╝██║
███████╗ ██║ ███████║ ██║ █████╗ ██████╔╝ ╚████╔╝ ██║ ⭐️ ✨
╚════██║ ██║ ██╔══██║ ██║ ██╔══╝ ██╔══██╗ ╚██╔╝ ╚═╝
███████║ ██║ ██║ ██║ ██║ ███████╗██║ ██║ ██║ ██╗ ✨ 💥
╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ✨
✨ ✨ ⭐️
SURPRISE-FREE STATE MANAGEMENT! 💥
✨
set
function for updating a store and not much else (have you checked out the demo yet?) If you want to use reducers or libraries like Immer, these can easily sit on top of your Statery store.useStore
hook makes use of proxies, the store contents themselves are never wrapped in proxy objects. (If you're looking for a fully proxy-based solution, I recommend Valtio.)import { makeStore, useStore } from "statery"
const store = makeStore({ counter: 0 })
const increment = () =>
store.set((state) => ({
counter: state.counter + 1
}))
const Counter = () => {
const { counter } = useStore(store)
return (
<div>
<p>Counter: {counter}</p>
<button onClick={increment}>Increment</button>
</div>
)
}
For a more fully-featured example, please check out the demo.
npm add statery
yarn add statery
pnpm add statery
Statery stores wrap around plain old JavaScript objects that are free to contain any kind of data:
import { value makeStore } from "statery"
const store = makeStore({
player: {
id: 1,
name: "John Doe",
email: "john@doe.com"
},
gold: 100,
wood: 0,
houses: 0
})
If you're using TypeScript, the type of the store state will be inferred from the initial state; but you may also pass a type argument to makeStore
to explicitly set the type of the store:
const store = makeStore<{ count: number }>({ count: 0 })
The store object's set
function will update the store's state and notify any listeners who have subscribed to changes:
const collectWood = () =>
store.set((state) => ({
wood: state.wood + 1
}))
const buildHouse = () =>
store.set((state) => ({
wood: state.wood - 10,
houses: state.houses + 1
}))
const Buttons = () => {
return (
<p>
<button onClick={collectWood}>Collect Wood</button>
<button onClick={buildHouse}>Build House</button>
</p>
)
}
Updates will be shallow-merged with the current state, meaning that top-level properties will be replaced, and properties you don't update will not be touched.
Within a React component, use the useStore
hook to read data from the store:
import { value useStore } from "statery"
const Wood = () => {
const { wood } = useStore(store)
return <p>Wood: {wood}</p>
}
When any of the store's properties that your component accesses are updated, they will automatically re-render, automatically receiving the new state.
A Statery store provides access to its current state through its state
property:
const store = makeStore({ count: 0 })
console.log(store.state.count)
You can also imperatively subscribe to updates.
Just like mutations, functions that derive values from the store's state can be written as standalone functions:
const canBuyHouse = ({ wood, gold }) => wood >= 5 && gold >= 5
These will work from within plain imperative JavaScript code...
if (canBuyHouse(store.state)) {
console.log("Let's buy a house!")
}
...mutation code...
const buyHouse = () =>
store.set((state) =>
canBuyHouse(state)
? {
wood: state.wood - 5,
gold: state.gold - 5,
houses: state.houses + 1
}
: {}
)
...as well as React components, which will automatically be re-rendered if any of the underlying data changes:
const BuyHouseButton = () => {
const store = useStore(store)
return (
<button onClick={buyHouse} disabled={!canBuyHouse(store)}>
Buy House (5g, 5w)
</button>
)
}
When the store is updated, Statery will check which of the properties within the update object are actually different objects (or scalar values) from the previous state, and will only notify listeners to those properties.
In some cases, you may want to force a store update even though the property has not changed to a new object. For these situations, the set
function allows you to pass a second argument; if this is set to true
, Statery will ignore the equality check and notify all listeners to the properties included in the update.
Example:
const store = makeStore({
rotation: new THREE.Vector3()
})
export const randomizeRotation = () =>
store.set(
(state) => ({
rotation: state.rotation.randomRotation()
}),
true
)
Use a store's subscribe
function to register a callback that will be executed every time the store is changed.
The callback will receive both an object containing of the changes, as well as the store's current state.
const store = makeStore({ count: 0 })
const listener = (changes, state) => {
console.log("Applying changes:", changes)
}
store.subscribe(console.log)
store.set((state) => ({ count: state.count + 1 }))
store.unsubscribe(console.log)
Statery was born after spending a lot of time with the excellent state management libraries provided by the Poimandres collective, Zustand and Valtio. Statery started out as an almost-clone of Zustand, but with the aim of providing an even simpler API. The useStore
hook API was inspired by Valtio's very nice useProxy
.
Statery is written and maintained by Hendrik Mans.
FAQs
A happy little state management library for React and friends.
The npm package statery receives a total of 45 weekly downloads. As such, statery popularity was classified as not popular.
We found that statery demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.