@simplestack/store 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -121
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,7 +33,10 @@ const documentStore = store({
|
|
|
33
33
|
|
|
34
34
|
function Document() {
|
|
35
35
|
// Update your UI with the store's current state
|
|
36
|
-
const {
|
|
36
|
+
const {
|
|
37
|
+
title,
|
|
38
|
+
meta: { tags },
|
|
39
|
+
} = useStoreValue(documentStore);
|
|
37
40
|
return (
|
|
38
41
|
<div>
|
|
39
42
|
{title} {tags.join(", ")}
|
|
@@ -54,126 +57,7 @@ function Title() {
|
|
|
54
57
|
}
|
|
55
58
|
```
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
### store(initial)
|
|
60
|
-
|
|
61
|
-
Creates a store with `get`, `set`, `subscribe`, and (for objects and arrays) `select`.
|
|
62
|
-
|
|
63
|
-
- Parameters: `initial: number | string | boolean | null | undefined | object`
|
|
64
|
-
- Returns: `Store<T>` where `T` is inferred from `initial` or supplied via generics
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
import { store } from "@simplestack/store";
|
|
68
|
-
|
|
69
|
-
const counter = store(0);
|
|
70
|
-
counter.set((n) => n + 1);
|
|
71
|
-
console.log(counter.get()); // 1
|
|
72
|
-
|
|
73
|
-
// Select parts of a store for objects and arrays
|
|
74
|
-
const doc = store({ title: "x" });
|
|
75
|
-
const title = doc.select("title");
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### React
|
|
79
|
-
|
|
80
|
-
#### useStoreValue(store, selector?)
|
|
81
|
-
|
|
82
|
-
A React hook to subscribe to a store and get its current value. Optionally pass a selector function to derive a value from the store.
|
|
83
|
-
|
|
84
|
-
- Parameters:
|
|
85
|
-
- `store: Store<T> | undefined`
|
|
86
|
-
- `selector?: (state: T) => R` - optional function to select/compute a value
|
|
87
|
-
- Returns: `R | T | undefined`
|
|
88
|
-
|
|
89
|
-
```tsx
|
|
90
|
-
import { store } from "@simplestack/store";
|
|
91
|
-
import { useStoreValue } from "@simplestack/store/react";
|
|
92
|
-
|
|
93
|
-
const counterStore = store(0);
|
|
94
|
-
|
|
95
|
-
function Counter() {
|
|
96
|
-
const counter = useStoreValue(counterStore);
|
|
97
|
-
return (
|
|
98
|
-
<button onClick={() => counterStore.set((n) => n + 1)}>{counter}</button>
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
With a selector:
|
|
104
|
-
|
|
105
|
-
```tsx
|
|
106
|
-
const documentStore = store({
|
|
107
|
-
notes: {
|
|
108
|
-
"1": { title: "First" },
|
|
109
|
-
"2": { title: "Second" },
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
function NoteTitle({ id }: { id: string }) {
|
|
114
|
-
// Only re-renders when this specific note's title changes
|
|
115
|
-
const title = useStoreValue(documentStore, (s) => s.notes[id]?.title);
|
|
116
|
-
return <h1>{title}</h1>;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function NoteCount() {
|
|
120
|
-
// Compute derived values inline
|
|
121
|
-
const count = useStoreValue(documentStore, (s) => Object.keys(s.notes).length);
|
|
122
|
-
return <span>{count} notes</span>;
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
#### useShallow(selector)
|
|
127
|
-
|
|
128
|
-
Wraps a selector with shallow equality comparison. Use this when your selector returns a new array or object reference on each call.
|
|
129
|
-
|
|
130
|
-
**The problem:** selectors that return new references (like `Object.values()`, array `filter()`, or object spreads) cause infinite re-renders because React sees a "new" value each time.
|
|
131
|
-
|
|
132
|
-
```tsx
|
|
133
|
-
import { useStoreValue, useShallow } from "@simplestack/store/react";
|
|
134
|
-
|
|
135
|
-
// ❌ BAD: Creates new array reference each render → infinite loop
|
|
136
|
-
const [title, author] = useStoreValue(noteStore, (s) => [s.title, s.author]);
|
|
137
|
-
|
|
138
|
-
// ✅ GOOD: useShallow compares array contents, stable reference
|
|
139
|
-
const [title, author] = useStoreValue(noteStore, useShallow((s) => [s.title, s.author]));
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
More examples:
|
|
143
|
-
|
|
144
|
-
```tsx
|
|
145
|
-
// Filtering creates new array
|
|
146
|
-
const drafts = useStoreValue(
|
|
147
|
-
docStore,
|
|
148
|
-
useShallow((s) => s.notes.filter((n) => n.isDraft))
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
// Spreading creates new object
|
|
152
|
-
const meta = useStoreValue(
|
|
153
|
-
docStore,
|
|
154
|
-
useShallow((s) => ({ title: s.title, author: s.author }))
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
// Object.keys/values/entries create new arrays
|
|
158
|
-
const ids = useStoreValue(
|
|
159
|
-
docStore,
|
|
160
|
-
useShallow((s) => Object.keys(s.notes))
|
|
161
|
-
);
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## Type Reference
|
|
165
|
-
|
|
166
|
-
These types are exported for TypeScript users.
|
|
167
|
-
|
|
168
|
-
- StateObject: `Record<string | number | symbol, any>`
|
|
169
|
-
- StatePrimitive: `string | number | boolean | null | undefined`
|
|
170
|
-
- Setter<T>: `T | ((state: T) => T)`
|
|
171
|
-
- Store<T>:
|
|
172
|
-
- `get(): T` - Get the current value of the store.
|
|
173
|
-
- `set(setter: Setter<T>): void` - Set the value directly or by using a function that receives the current state.
|
|
174
|
-
- `subscribe(callback: (state: T) => void): () => void` - Subscribe with a callback. Returns an unsubscribe function.
|
|
175
|
-
- `select(key: K): Store<SelectValue<T, K>>` (present only when `T` is an object or array) - Select a key or array index of the store. Returns a nested Store.
|
|
176
|
-
- `getInitial(): T` - Get the initial state the store was created with. Used internally for SSR resume-ability.
|
|
60
|
+
📚 For a complete usage guide and API reference, [visit our documentation](https://simple-stack.dev/store).
|
|
177
61
|
|
|
178
62
|
## Contributing
|
|
179
63
|
|