@sheldom/state
v0.1.1
Published
State system package of the sheldom library.
Readme
@sheldom/state
Reactive state for Web Components, without the framework.
@sheldom/state gives you a @state decorator that turns a class field into a reactive one — set it, and requestUpdate() gets called for you. No store, no proxies over your whole object graph, no framework runtime: just a small State<T> primitive and a few decorators built on top of it.
✨ Features
⚡ @state fields
Decorate a field, get automatic re-renders on every change — deduped with Object.is, so setting the same value twice is a no-op.
🌍 Shared state across components
@globalState and useGlobalState let unrelated components read and write the exact same piece of state by name.
👀 @watch a state's changes
React to a state changing without owning it — call a method whenever a named state updates.
🧠 Just a State<T> underneath
Every decorator is a thin layer over a plain State<T> class with subscribe/unsubscribe. Use it directly if you don't need the decorators.
🔌 Framework-agnostic
Works with anything that implements a tiny Updatable contract — @sheldom/core's Component, or your own classes.
📦 Install
npm install @sheldom/state🚀 Usage
import { Component } from "@sheldom/core";
import { html } from "@sheldom/dom";
import { state, watch } from "@sheldom/state";
export default class Counter extends Component {
@state count = 0;
@watch("count")
onCountChanged(value: number) {
console.log("count is now", value);
}
render() {
return html`
<button @click=${() => this.count++}>Count: ${this.count}</button>
`;
}
}Share a value across components with @globalState:
import { Component } from "@sheldom/core";
import { globalState } from "@sheldom/state";
export default class Cart extends Component {
@globalState("cart-count") itemCount = 0;
}Any other component using @globalState("cart-count") reads and writes the same value — updating one re-renders every component watching it.
Prefer no decorators at all? Use State<T> directly:
import { State } from "@sheldom/state";
const theme = new State<"light" | "dark">("light");
const unsubscribe = theme.subscribe((value) => console.log("theme:", value));
theme.value = "dark"; // logs "theme: dark"🌱 Part of the Sheldom toolkit
@sheldom/state only depends on @sheldom/core-contracts — it doesn't need @sheldom/core or any rendering engine to work. Most projects should install sheldom instead, which bundles it together with Component and html.
📄 License
MIT — see LICENSE.
