@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/readme.md +93 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartstate",
3
- "version": "2.0.20",
3
+ "version": "2.0.21",
4
4
  "private": false,
5
5
  "description": "A package for handling and managing state in applications.",
6
6
  "main": "dist_ts/index.js",
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 npm (Node Package Manager). Run the following command in your terminal:
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
- npm install @push.rocks/smartstate --save
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 the concept of persistent states, where you can maintain state across sessions. To utilize this, specify a persistent mode when getting a state part:
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<AppStateParts, ISettingsState>(
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
- This mode ensures that the state is saved and can be reloaded even after the application restarts, providing a seamless user experience.
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
- Remember to leverage TypeScript for its excellent support for types and interfaces, enhancing your development experience with type checking and IntelliSense, ensuring a more reliable and maintainable codebase.
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 Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
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
- Task Venture Capital GmbH
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@task.vc.
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 Task Venture Capital GmbH of any derivative works.
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.