state-jet 2.0.6 → 2.0.8

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.
Files changed (2) hide show
  1. package/README.md +171 -14
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # 🚀 state-jet: Ultra-Lightweight Global State for React
1
+ A zero-boilerplate, ultra-fast global state management library for React.
2
2
 
3
- A zero-boilerplate, ultra-fast global state management library for React. No context, reducers, or providers—just simple reactive state.
4
-
5
- For more Information, see [here](https://statejet.netlify.app).
3
+ For more details, see [here](https://statejet.netlify.app).
6
4
 
7
5
  ## 🚀 Why state-jet?
8
6
 
@@ -43,7 +41,7 @@ Or if you're using `cdn`:
43
41
 
44
42
  ## Basic Example Usage
45
43
 
46
- ```bash
44
+ ```tsx
47
45
  import { useStateGlobal } from "state-jet";
48
46
 
49
47
  const counter = useStateGlobal("counter", 0);
@@ -53,7 +51,7 @@ function Counter() {
53
51
  return <button onClick={() => counter.set(count + 1)}>Count: {count}</button>;
54
52
  }
55
53
  ```
56
- ## Why state-jet Is More Advanced Than Zustand
54
+ ## Why state-jet Is More Advanced Than Zustand
57
55
 
58
56
  - **No Proxies Needed** → Zustand uses proxies for state updates, but state-jet uses signals, making it even faster.
59
57
  - **Derived State Is Automatic** → No need for selectors; state updates only trigger where necessary.
@@ -61,26 +59,27 @@ function Counter() {
61
59
  - **Multi-Tab Sync** → global state persists across browser tabs and devices.
62
60
  - **CRDT Support** → Automatic conflict resolution for real-time apps, something even Zustand lacks.
63
61
 
64
- ### ✅Conclusion
62
+ ### ✅ Conclusion
65
63
 
66
64
  If you need the simplest, fastest, and most advanced state management solution for React, state-jet beats Redux, Recoil, MobX, Jotai, and even Zustand in performance, reactivity, and developer experience. 🚀
67
65
 
68
66
  ## Create Slice
69
67
 
70
- ```bash
68
+ ```tsx
71
69
  import { useSlice } from "state-jet";
72
70
 
73
- export const useProductSlice = () => useSlice("products")("list", []);
74
-
75
- export const useCartSlice = () =>
76
- useSlice("cart")("items", []);
71
+ const productSlice = useSlice("products");
72
+ const cartSlice = useSlice("cart");
73
+ const userSlice = useSlice("user");
77
74
 
78
- export const useUserSlice = () => useSlice("user")("info", null);
75
+ export const useProductSlice = () => productSlice("list", []);
76
+ export const useCartSlice = () => cartSlice("items", []);
77
+ export const useUserSlice = () => userSlice("info", null);
79
78
  ```
80
79
 
81
80
  ## Create Store
82
81
 
83
- ```bash
82
+ ```tsx
84
83
  import { useStore } from "state-jet";
85
84
  import { useProductSlice, useCartSlice, useUserSlice } from "./slices";
86
85
 
@@ -93,6 +92,164 @@ const initializer: any = () => ({
93
92
  export const useEcommerceStore = () => useStore(initializer);
94
93
  ```
95
94
 
95
+ ## Middlewares
96
+
97
+ Unlike other libraries, you do not need to rely on any external dependencies. A `middleware` property from `options` helps to add middleware for state-jet.
98
+
99
+ ```bash
100
+ function useStateGlobal<T>(
101
+ ...
102
+ options?: { middleware?: Middleware<T>[] }
103
+ )
104
+ ```
105
+
106
+ ### Logger Middleware
107
+
108
+ You can log your store for every action.
109
+
110
+ ```tsx
111
+ import { useStateGlobal } from "state-jet";
112
+
113
+ const loggerMiddleware = (key: string, prev: number, next: number) => {
114
+ console.log(`[state-jet] ${key}: ${prev} → ${next}`);
115
+ };
116
+
117
+ const counter = useStateGlobal("counter", 0, { middleware: [loggerMiddleware] });
118
+
119
+ export default function Counter() {
120
+ const count = counter.useState() as number;
121
+
122
+ return (
123
+ <div>
124
+ <h1>Counter: {count}</h1>
125
+ <button onClick={() => counter.set(count - 1)}>Decrement</button>
126
+ <button onClick={() => counter.set(count + 1)}>Increment</button>
127
+ </div>
128
+ );
129
+ }
130
+ ```
131
+
132
+ ### Reducer Middleware
133
+
134
+ Can't live without reducer?. No worries. StateJet supports reducer middleware
135
+
136
+ ```tsx
137
+ import { useStateGlobal } from "state-jet";
138
+
139
+ type Action<T> = { type: string; payload?: T };
140
+ type Middleware<T> = (
141
+ key: string,
142
+ prev: T,
143
+ next: T | Action<T> | any,
144
+ set?: (value: T) => void,
145
+ ) => T | void | Promise<void>;
146
+
147
+ const reducerMiddleware: Middleware<number> = (key, prev, action: Action<any>) => {
148
+ switch (action.type) {
149
+ case "INCREMENT":
150
+ return prev + 1;
151
+ case "DECREMENT":
152
+ return prev - 1;
153
+ case "RESET":
154
+ return 0;
155
+ default:
156
+ return prev;
157
+ }
158
+ }
159
+
160
+ const counter = useStateGlobal("counter", 0, { middleware: [reducerMiddleware] });
161
+
162
+ export default function Counter() {
163
+ const count = counter.useState() as number;
164
+
165
+ return (
166
+ <div>
167
+ <h1>Counter: {count}</h1>
168
+ <button onClick={() => counter.set({ type: "DECREMENT" })}>Decrement</button>
169
+ <button onClick={() => counter.set({ type: "INCREMENT" })}>Increment</button>
170
+ <button onClick={() => counter.set({ type: "RESET" })}>Reset</button>
171
+ </div>
172
+ );
173
+ }
174
+ ```
175
+
176
+ ### Optimistic Middleware
177
+
178
+ You can optimistically update global state with rollback support
179
+
180
+ ```tsx
181
+ import { useStateGlobal } from "state-jet";
182
+
183
+ const optimisticMiddleware = (apiUrl: string) => {
184
+ return async (key: string, prev: number, next: number, set: any) => {
185
+ set(next); // Optimistically update state
186
+
187
+ try {
188
+ await fetch(apiUrl, {
189
+ method: "POST",
190
+ body: JSON.stringify({ key, value: next }),
191
+ headers: { "Content-Type": "application/json" },
192
+ });
193
+ } catch (error) {
194
+ console.warn(`[state-jet] Rollback: Failed to sync ${key}`);
195
+ set(prev); // Rollback state on failure
196
+ }
197
+ };
198
+ };
199
+ const profile = useStateGlobal("profile", { name: "John" }, {
200
+ middleware: [optimisticMiddleware("/update-profile")],
201
+ });
202
+ ```
203
+
204
+ ### Custom Middleware
205
+
206
+ You can create your own custom middleware in state-jet
207
+
208
+ ```tsx
209
+ import { useStateGlobal } from "state-jet";
210
+
211
+ const validateAgeMiddleware = (key: string, prev: number, next: number) => {
212
+ if (key === "age" && next < 0) {
213
+ console.warn("Age cannot be negative!");
214
+ return prev;
215
+ }
216
+ return next;
217
+ };
218
+ const ageState = useStateGlobal("age", 0, { middleware: [validateAgeMiddleware] });
219
+
220
+ export default function Profile() {
221
+ const age = ageState.useState() as number;
222
+
223
+ return (
224
+ <div>
225
+ <h1>Age: {age}</h1>
226
+ <button
227
+ onClick={() => {
228
+ counter.set(-5) //Age will be 0 eventhough it updated with negative value due to middleware logic
229
+ }}>
230
+ Set negative
231
+ </button>
232
+ </div>
233
+ );
234
+ }
235
+ ```
236
+
237
+ A more complete middleware usage is [here](https://statejet.netlify.app/docs/api-reference/middlewares/).
238
+
239
+ ## Typescript Usage
240
+
241
+ Here is the example for creating global state with typescript definition.
242
+
243
+ ```tsx
244
+ interface Todo = {
245
+ id: number;
246
+ text: string;
247
+ completed: boolean
248
+ };
249
+
250
+ const todoState = useStateGlobal<Todo[]>("todos", []);
251
+ ```
252
+
96
253
  ## ⚡ Comparison Table
97
254
  | Feature | Redux | Recoil | MobX | Jotai | Zustand | state-jet |
98
255
  |--------------------------|--------|--------|-------|--------|------------------------|----------------------|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "state-jet",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "Ultra-lightweight global state management for React",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",