@push.rocks/smartstate 2.0.20 → 2.0.21
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/package.json +1 -1
- package/readme.md +93 -13
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -3,10 +3,10 @@ a package that handles state in a good way
|
|
|
3
3
|
|
|
4
4
|
## Install
|
|
5
5
|
|
|
6
|
-
To install `@push.rocks/smartstate`, you can use
|
|
6
|
+
To install `@push.rocks/smartstate`, you can use pnpm (Performant Node Package Manager). Run the following command in your terminal:
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
|
|
9
|
+
pnpm install @push.rocks/smartstate --save
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
This will add `@push.rocks/smartstate` to your project's dependencies.
|
|
@@ -31,6 +31,15 @@ import { Smartstate, StatePart, StateAction } from '@push.rocks/smartstate';
|
|
|
31
31
|
const myAppSmartState = new Smartstate<YourStatePartNamesEnum>();
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
### Understanding Init Modes
|
|
35
|
+
|
|
36
|
+
When creating state parts, you can specify different initialization modes:
|
|
37
|
+
|
|
38
|
+
- **`'soft'`** - Allows existing state parts to remain (default behavior)
|
|
39
|
+
- **`'mandatory'`** - Fails if there's an existing state part with the same name
|
|
40
|
+
- **`'force'`** - Overwrites any existing state part
|
|
41
|
+
- **`'persistent'`** - Enables WebStore persistence using IndexedDB
|
|
42
|
+
|
|
34
43
|
### Defining State Parts
|
|
35
44
|
|
|
36
45
|
State parts represent separable sections of your state, making it easier to manage and modularize. For example, you may have a state part for user data and another for application settings.
|
|
@@ -54,8 +63,14 @@ interface IUserState {
|
|
|
54
63
|
|
|
55
64
|
const userStatePart = await myAppSmartState.getStatePart<IUserState>(
|
|
56
65
|
AppStateParts.UserState,
|
|
57
|
-
{ isLoggedIn: false } // Initial state
|
|
66
|
+
{ isLoggedIn: false }, // Initial state
|
|
67
|
+
'soft' // Init mode (optional, defaults to 'soft')
|
|
58
68
|
);
|
|
69
|
+
|
|
70
|
+
// For persistent state parts, you must call init()
|
|
71
|
+
if (mode === 'persistent') {
|
|
72
|
+
await userStatePart.init();
|
|
73
|
+
}
|
|
59
74
|
```
|
|
60
75
|
|
|
61
76
|
### Subscribing to State Changes
|
|
@@ -92,28 +107,93 @@ const loginUserAction = userStatePart.createAction<ILoginPayload>(async (statePa
|
|
|
92
107
|
});
|
|
93
108
|
|
|
94
109
|
// Dispatch the action to update the state
|
|
95
|
-
loginUserAction.trigger({ username: 'johnDoe' });
|
|
110
|
+
await loginUserAction.trigger({ username: 'johnDoe' });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Additional State Methods
|
|
114
|
+
|
|
115
|
+
`StatePart` provides several useful methods for state management:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// Wait for a specific state condition
|
|
119
|
+
await userStatePart.waitUntilPresent();
|
|
120
|
+
|
|
121
|
+
// Setup initial state with async operations
|
|
122
|
+
await userStatePart.stateSetup(async (state) => {
|
|
123
|
+
// Perform async initialization
|
|
124
|
+
const userData = await fetchUserData();
|
|
125
|
+
return { ...state, ...userData };
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Batch multiple state changes for cumulative notification
|
|
129
|
+
userStatePart.notifyChangeCumulative(() => {
|
|
130
|
+
// Multiple state changes here will result in a single notification
|
|
131
|
+
});
|
|
96
132
|
```
|
|
97
133
|
|
|
98
|
-
### Persistent State
|
|
134
|
+
### Persistent State with WebStore
|
|
99
135
|
|
|
100
|
-
`Smartstate` supports
|
|
136
|
+
`Smartstate` supports persistent states using WebStore (IndexedDB-based storage), allowing you to maintain state across sessions:
|
|
101
137
|
|
|
102
138
|
```typescript
|
|
103
|
-
const settingsStatePart = await myAppSmartState.getStatePart<
|
|
139
|
+
const settingsStatePart = await myAppSmartState.getStatePart<ISettingsState>(
|
|
104
140
|
AppStateParts.SettingsState,
|
|
105
141
|
{ theme: 'light' }, // Initial state
|
|
106
142
|
'persistent' // Mode
|
|
107
143
|
);
|
|
144
|
+
|
|
145
|
+
// Initialize the persistent state (required for persistent mode)
|
|
146
|
+
await settingsStatePart.init();
|
|
108
147
|
```
|
|
109
148
|
|
|
110
|
-
|
|
149
|
+
Persistent state automatically:
|
|
150
|
+
- Saves state changes to IndexedDB
|
|
151
|
+
- Restores state on application restart
|
|
152
|
+
- Manages storage with configurable database and store names
|
|
153
|
+
|
|
154
|
+
### Performance Optimization
|
|
155
|
+
|
|
156
|
+
`Smartstate` includes built-in performance optimizations:
|
|
157
|
+
|
|
158
|
+
- **State Hash Detection**: Uses SHA256 hashing to detect actual state changes, preventing unnecessary notifications when state values haven't truly changed
|
|
159
|
+
- **Cumulative Notifications**: Batch multiple state changes into a single notification using `notifyChangeCumulative()`
|
|
160
|
+
- **Selective Subscriptions**: Use selectors to subscribe only to specific state properties
|
|
161
|
+
|
|
162
|
+
### RxJS Integration
|
|
163
|
+
|
|
164
|
+
`Smartstate` leverages RxJS for reactive state management:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// State is exposed as an RxJS Subject
|
|
168
|
+
const stateObservable = userStatePart.select();
|
|
169
|
+
|
|
170
|
+
// Automatically starts with current state value
|
|
171
|
+
stateObservable.subscribe((state) => {
|
|
172
|
+
console.log('Current state:', state);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Use selectors for specific properties
|
|
176
|
+
userStatePart.select(state => state.username)
|
|
177
|
+
.pipe(
|
|
178
|
+
distinctUntilChanged(),
|
|
179
|
+
filter(username => username !== undefined)
|
|
180
|
+
)
|
|
181
|
+
.subscribe(username => {
|
|
182
|
+
console.log('Username changed:', username);
|
|
183
|
+
});
|
|
184
|
+
```
|
|
111
185
|
|
|
112
186
|
### Comprehensive Usage
|
|
113
187
|
|
|
114
188
|
Putting it all together, `@push.rocks/smartstate` offers a flexible and powerful pattern for managing application state. By modularizing state parts, subscribing to state changes, and controlling state modifications through actions, developers can maintain a clean and scalable architecture. Combining these strategies with persistent states unlocks the full potential for creating dynamic and user-friendly applications.
|
|
115
189
|
|
|
116
|
-
|
|
190
|
+
Key features:
|
|
191
|
+
- **Type-safe state management** with full TypeScript support
|
|
192
|
+
- **Reactive state updates** using RxJS observables
|
|
193
|
+
- **Persistent state** with IndexedDB storage
|
|
194
|
+
- **Performance optimized** with state hash detection
|
|
195
|
+
- **Modular architecture** with separate state parts
|
|
196
|
+
- **Action-based updates** for predictable state modifications
|
|
117
197
|
|
|
118
198
|
For more complex scenarios, consider combining multiple state parts, creating hierarchical state structures, and integrating with other state management solutions as needed. With `@push.rocks/smartstate`, the possibilities are vast, empowering you to tailor the state management approach to fit the unique requirements of your project.
|
|
119
199
|
|
|
@@ -125,13 +205,13 @@ This repository contains open-source code that is licensed under the MIT License
|
|
|
125
205
|
|
|
126
206
|
### Trademarks
|
|
127
207
|
|
|
128
|
-
This project is owned and maintained by
|
|
208
|
+
This project is owned and maintained by Lossless GmbH. The names and logos associated with Lossless GmbH and any related products or services are trademarks of Lossless GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Lossless GmbH's Trademark Guidelines, and any usage must be approved in writing by Lossless GmbH.
|
|
129
209
|
|
|
130
210
|
### Company Information
|
|
131
211
|
|
|
132
|
-
|
|
212
|
+
Lossless GmbH
|
|
133
213
|
Registered at District court Bremen HRB 35230 HB, Germany
|
|
134
214
|
|
|
135
|
-
For any legal inquiries or if you require further information, please contact us via email at hello@
|
|
215
|
+
For any legal inquiries or if you require further information, please contact us via email at hello@lossless.com.
|
|
136
216
|
|
|
137
|
-
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by
|
|
217
|
+
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Lossless GmbH of any derivative works.
|