state-jet 2.0.5 β†’ 2.0.7

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 +198 -51
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # πŸš€ state-jet: Ultra-Lightweight Global State for React
2
-
3
1
  A zero-boilerplate, ultra-fast global state management library for React. No context, reducers, or providersβ€”just simple reactive state.
4
2
 
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
 
@@ -53,6 +51,203 @@ function Counter() {
53
51
  return <button onClick={() => counter.set(count + 1)}>Count: {count}</button>;
54
52
  }
55
53
  ```
54
+ ## ⚑ Why state-jet Is More Advanced Than Zustand
55
+
56
+ - **No Proxies Needed** β†’ Zustand uses proxies for state updates, but state-jet uses signals, making it even faster.
57
+ - **Derived State Is Automatic** β†’ No need for selectors; state updates only trigger where necessary.
58
+ - **Optimistic Updates & Rollback** β†’ Unlike Zustand, state-jet has built-in support for instant UI updates and auto-revert on failures.
59
+ - **Multi-Tab Sync** β†’ global state persists across browser tabs and devices.
60
+ - **CRDT Support** β†’ Automatic conflict resolution for real-time apps, something even Zustand lacks.
61
+
62
+ ### βœ… Conclusion
63
+
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. πŸš€
65
+
66
+ ## Create Slice
67
+
68
+ ```bash
69
+ import { useSlice } from "state-jet";
70
+
71
+ export const useProductSlice = () => useSlice("products")("list", []);
72
+
73
+ export const useCartSlice = () =>
74
+ useSlice("cart")("items", []);
75
+
76
+ export const useUserSlice = () => useSlice("user")("info", null);
77
+ ```
78
+
79
+ ## Create Store
80
+
81
+ ```bash
82
+ import { useStore } from "state-jet";
83
+ import { useProductSlice, useCartSlice, useUserSlice } from "./slices";
84
+
85
+ const initializer: any = () => ({
86
+ products: useProductSlice(),
87
+ cart: useCartSlice(),
88
+ user: useUserSlice()
89
+ });
90
+
91
+ export const useEcommerceStore = () => useStore(initializer);
92
+ ```
93
+
94
+ ## Middlewares
95
+
96
+ 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.
97
+
98
+ ```bash
99
+ function useStateGlobal<T>(
100
+ ...
101
+ options?: { middleware?: Middleware<T>[] }
102
+ )
103
+ ```
104
+
105
+ ### Logger Middleware
106
+
107
+ You can log your store for every action.
108
+
109
+ ```bash
110
+ import { useStateGlobal } from "state-jet";
111
+
112
+ const loggerMiddleware = (key: string, prev: number, next: number) => {
113
+ console.log(`[state-jet] ${key}: ${prev} β†’ ${next}`);
114
+ };
115
+
116
+ const counter = useStateGlobal("counter", 0, { middleware: [loggerMiddleware] });
117
+
118
+ export default function Counter() {
119
+ const count = counter.useState() as number;
120
+
121
+ return (
122
+ <div>
123
+ <h1>Counter: {count}</h1>
124
+ <button onClick={() => counter.set(count - 1)}>Decrement</button>
125
+ <button onClick={() => counter.set(count + 1)}>Increment</button>
126
+ </div>
127
+ );
128
+ }
129
+ ```
130
+
131
+ ### Reducer Middleware
132
+
133
+ Can't live without reducer?. No worries. StateJet supports reducer middleware
134
+
135
+ ```bash
136
+ import { useStateGlobal } from "state-jet";
137
+
138
+ type Action<T> = { type: string; payload?: T };
139
+ type Middleware<T> = (
140
+ key: string,
141
+ prev: T,
142
+ next: T | Action<T> | any,
143
+ set?: (value: T) => void,
144
+ ) => T | void | Promise<void>;
145
+
146
+ const reducerMiddleware: Middleware<number> = (key, prev, action: Action<any>) => {
147
+ switch (action.type) {
148
+ case "INCREMENT":
149
+ return prev + 1;
150
+ case "DECREMENT":
151
+ return prev - 1;
152
+ case "RESET":
153
+ return 0;
154
+ default:
155
+ return prev;
156
+ }
157
+ }
158
+
159
+ const counter = useStateGlobal("counter", 0, { middleware: [reducerMiddleware] });
160
+
161
+ export default function Counter() {
162
+ const count = counter.useState() as number;
163
+
164
+ return (
165
+ <div>
166
+ <h1>Counter: {count}</h1>
167
+ <button onClick={() => counter.set({ type: "DECREMENT" })}>Decrement</button>
168
+ <button onClick={() => counter.set({ type: "INCREMENT" })}>Increment</button>
169
+ <button onClick={() => counter.set({ type: "RESET" })}>Reset</button>
170
+ </div>
171
+ );
172
+ }
173
+ ```
174
+
175
+ ### Optimistic Middleware
176
+
177
+ You can optimistically update global state with rollback support
178
+
179
+ ```bash
180
+ import { useStateGlobal } from "state-jet";
181
+
182
+ const optimisticMiddleware = (apiUrl: string) => {
183
+ return async (key: string, prev: number, next: number, set: any) => {
184
+ set(next); // Optimistically update state
185
+
186
+ try {
187
+ await fetch(apiUrl, {
188
+ method: "POST",
189
+ body: JSON.stringify({ key, value: next }),
190
+ headers: { "Content-Type": "application/json" },
191
+ });
192
+ } catch (error) {
193
+ console.warn(`[state-jet] Rollback: Failed to sync ${key}`);
194
+ set(prev); // Rollback state on failure
195
+ }
196
+ };
197
+ };
198
+ const profile = useStateGlobal("profile", { name: "John" }, {
199
+ middleware: [optimisticMiddleware("/update-profile")],
200
+ });
201
+ ```
202
+
203
+ ### Custom Middleware
204
+
205
+ You can create your own custom middleware in state-jet
206
+
207
+ ```bash
208
+ import { useStateGlobal } from "state-jet";
209
+
210
+ const validateAgeMiddleware = (key: string, prev: number, next: number) => {
211
+ if (key === "age" && next < 0) {
212
+ console.warn("Age cannot be negative!");
213
+ return prev;
214
+ }
215
+ return next;
216
+ };
217
+ const ageState = useStateGlobal("age", 0, { middleware: [validateAgeMiddleware] });
218
+
219
+ export default function Profile() {
220
+ const age = ageState.useState() as number;
221
+
222
+ return (
223
+ <div>
224
+ <h1>Age: {age}</h1>
225
+ <button
226
+ onClick={() => {
227
+ counter.set(-5) //Age will be 0 eventhough it updated with negative value due to middleware logic
228
+ }}>
229
+ Set negative
230
+ </button>
231
+ </div>
232
+ );
233
+ }
234
+ ```
235
+
236
+ A more complete middleware usage is [here](https://statejet.netlify.app/docs/api-reference/middlewares/).
237
+
238
+ ## Typescript Usage
239
+
240
+ Here is the example for creating global state with typescript definition.
241
+
242
+ ```bash
243
+ interface Todo = {
244
+ id: number;
245
+ text: string;
246
+ completed: boolean
247
+ };
248
+
249
+ const todoState = useStateGlobal<Todo[]>("todos", []);
250
+ ```
56
251
 
57
252
  ## ⚑ Comparison Table
58
253
  | Feature | Redux | Recoil | MobX | Jotai | Zustand | state-jet |
@@ -67,54 +262,6 @@ function Counter() {
67
262
  | **CRDT Conflict Resolution** | ❌ No | ❌ No | ❌ No | ❌ No | ❌ No | βœ… Yes |
68
263
 
69
264
 
70
- ## ⚑ Why state-jet Is More Advanced Than Zustand
71
-
72
- - **No Proxies Needed** β†’ Zustand uses proxies for state updates, but state-jet uses signals, making it even faster.
73
- - **Derived State Is Automatic** β†’ No need for selectors; state updates only trigger where necessary.
74
- - **Optimistic Updates & Rollback** β†’ Unlike Zustand, state-jet has built-in support for instant UI updates and auto-revert on failures.
75
- - **Multi-Tab Sync** β†’ global state persists across browser tabs and devices.
76
- - **CRDT Support** β†’ Automatic conflict resolution for real-time apps, something even Zustand lacks.
77
-
78
- βœ… Conclusion
79
-
80
- 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. πŸš€
81
-
82
- ## 🎯 Why Use `optimisticUpdate`?
83
-
84
- | Feature | Without `optimisticUpdate` | With `optimisticUpdate` |
85
- | ----------------------- | -------------------------- | --------------------------- |
86
- | **UI Responsiveness** | Delayed (Waits for API) | Instant update (Optimistic) |
87
- | **User Experience** | Slow & Janky | Fast & Smooth |
88
- | **Rollback on Failure** | Manual Handling | Automatic |
89
- | **Code Complexity** | High | Low |
90
-
91
- ## 🎯 Why Use `syncCRDT`?
92
-
93
- | Feature | Without `syncCRDT` | With `syncCRDT` |
94
- | ---------------------- | ------------------ | -------------------------- |
95
- | **Multi-User Sync** | Possible Conflicts | βœ… Automatic Merging |
96
- | **Real-Time Updates** | Needs Manual Fixes | βœ… No Data Loss |
97
- | **Handles Conflicts** | Can Lose Changes | βœ… Merges Automatically |
98
- | **Scalable for Teams** | Hard to Maintain | βœ… Ideal for Collaboration |
99
-
100
- ## 🎯 Why Use `derivedState`?
101
-
102
- | Feature | Without `derivedState` | With `derivedState` |
103
- | ------------------------- | --------------------------- | ------------------------------ |
104
- | **Manual Recalculations** | ❌ Yes (Recompute manually) | βœ… Automatic |
105
- | **Reactivity** | ❌ Requires `useEffect` | βœ… Updates only when needed |
106
- | **Performance** | ❌ Unoptimized | βœ… Only recalculates on change |
107
- | **Code Complexity** | ❌ High | βœ… Minimal |
108
-
109
- ## 🎯 Why Use `undo & redo`?
110
-
111
- | Feature | Without Undo/Redo | With Undo/Redo |
112
- | ---------------------- | ------------------------ | -------------------------- |
113
- | **Accidental Changes** | ❌ Lost forever | βœ… Easily undone |
114
- | **User Experience** | ❌ Frustrating | βœ… Smooth & intuitive |
115
- | **Multi-Step Editing** | ❌ Hard to track | βœ… Easy to restore history |
116
- | **Performance** | ❌ Needs manual tracking | βœ… Automatic |
117
-
118
265
  ## Contributing
119
266
 
120
267
  Development of State-jet happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving State-jet.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "state-jet",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "Ultra-lightweight global state management for React",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",