Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d8decdb3e5 | |||
| 03cfee2003 |
11
changelog.md
11
changelog.md
@@ -1,5 +1,16 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-02-02 - 2.0.30 - fix(config)
|
||||||
|
update npmextra configuration and improve README: rename package keys, add release registry config, clarify waitUntilPresent timeout and notification/persistence behavior
|
||||||
|
|
||||||
|
- Renamed npmextra keys: 'gitzone' → '@git.zone/cli' and 'tsdoc' → '@git.zone/tsdoc'
|
||||||
|
- Added release configuration for @git.zone/cli including registries (verdaccio and npm) and accessLevel
|
||||||
|
- Removed top-level 'npmci' section
|
||||||
|
- Added new '@ship.zone/szci' entry with npmGlobalTools
|
||||||
|
- README: added waitUntilPresent timeout example with error handling
|
||||||
|
- README: clarified notifyChangeCumulative is debounced and documented persistence behavior (merge with defaults, atomic writes)
|
||||||
|
- README: documented concurrency/race-condition safety and timeout support for waitUntilPresent
|
||||||
|
|
||||||
## 2026-02-02 - 2.0.29 - fix(smartstate)
|
## 2026-02-02 - 2.0.29 - fix(smartstate)
|
||||||
prevent duplicate statepart creation and fix persistence/notification race conditions
|
prevent duplicate statepart creation and fix persistence/notification race conditions
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
{
|
{
|
||||||
"npmci": {
|
|
||||||
"npmGlobalTools": [],
|
|
||||||
"npmAccessLevel": "public"
|
|
||||||
},
|
|
||||||
"@git.zone/tsbundle": {
|
"@git.zone/tsbundle": {
|
||||||
"bundles": [
|
"bundles": [
|
||||||
{
|
{
|
||||||
@@ -14,7 +10,7 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"gitzone": {
|
"@git.zone/cli": {
|
||||||
"projectType": "npm",
|
"projectType": "npm",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "code.foss.global",
|
"githost": "code.foss.global",
|
||||||
@@ -35,9 +31,19 @@
|
|||||||
"asynchronous state",
|
"asynchronous state",
|
||||||
"cumulative notification"
|
"cumulative notification"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"registries": [
|
||||||
|
"https://verdaccio.lossless.digital",
|
||||||
|
"https://registry.npmjs.org"
|
||||||
|
],
|
||||||
|
"accessLevel": "public"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tsdoc": {
|
"@git.zone/tsdoc": {
|
||||||
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis 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.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy 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.\n"
|
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis 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.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy 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.\n"
|
||||||
|
},
|
||||||
|
"@ship.zone/szci": {
|
||||||
|
"npmGlobalTools": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@push.rocks/smartstate",
|
"name": "@push.rocks/smartstate",
|
||||||
"version": "2.0.29",
|
"version": "2.0.30",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "A package for handling and managing state in applications.",
|
"description": "A package for handling and managing state in applications.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
|
|||||||
21
readme.md
21
readme.md
@@ -145,19 +145,26 @@ if (currentState) {
|
|||||||
console.log('Current user:', currentState.username);
|
console.log('Current user:', currentState.username);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for a specific state condition
|
// Wait for state to be present
|
||||||
await userStatePart.waitUntilPresent();
|
await userStatePart.waitUntilPresent();
|
||||||
|
|
||||||
// Wait for a specific property to be present
|
// Wait for a specific property to be present
|
||||||
await userStatePart.waitUntilPresent(state => state.username);
|
await userStatePart.waitUntilPresent(state => state.username);
|
||||||
|
|
||||||
|
// Wait with a timeout (throws error if condition not met within timeout)
|
||||||
|
try {
|
||||||
|
await userStatePart.waitUntilPresent(state => state.username, 5000); // 5 second timeout
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Timed out waiting for username');
|
||||||
|
}
|
||||||
|
|
||||||
// Setup initial state with async operations
|
// Setup initial state with async operations
|
||||||
await userStatePart.stateSetup(async (statePart) => {
|
await userStatePart.stateSetup(async (statePart) => {
|
||||||
const userData = await fetchUserData();
|
const userData = await fetchUserData();
|
||||||
return { ...statePart.getState(), ...userData };
|
return { ...statePart.getState(), ...userData };
|
||||||
});
|
});
|
||||||
|
|
||||||
// Defer notification to end of call stack
|
// Defer notification to end of call stack (debounced)
|
||||||
userStatePart.notifyChangeCumulative();
|
userStatePart.notifyChangeCumulative();
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -168,7 +175,7 @@ userStatePart.notifyChangeCumulative();
|
|||||||
```typescript
|
```typescript
|
||||||
const settingsStatePart = await myAppSmartState.getStatePart<ISettingsState>(
|
const settingsStatePart = await myAppSmartState.getStatePart<ISettingsState>(
|
||||||
AppStateParts.SettingsState,
|
AppStateParts.SettingsState,
|
||||||
{ theme: 'light' }, // Initial state
|
{ theme: 'light' }, // Initial/default state
|
||||||
'persistent' // Mode
|
'persistent' // Mode
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
@@ -176,7 +183,8 @@ const settingsStatePart = await myAppSmartState.getStatePart<ISettingsState>(
|
|||||||
Persistent state automatically:
|
Persistent state automatically:
|
||||||
- Saves state changes to IndexedDB
|
- Saves state changes to IndexedDB
|
||||||
- Restores state on application restart
|
- Restores state on application restart
|
||||||
- Manages storage with configurable database and store names
|
- Merges persisted values with defaults (persisted values take precedence)
|
||||||
|
- Ensures atomic writes (persistence happens before memory update)
|
||||||
|
|
||||||
### State Validation
|
### State Validation
|
||||||
|
|
||||||
@@ -200,9 +208,10 @@ class ValidatedStatePart<T> extends StatePart<string, T> {
|
|||||||
|
|
||||||
- **🔒 Async State Hash Detection**: Uses SHA256 hashing to detect actual state changes, preventing unnecessary notifications when state values haven't truly changed
|
- **🔒 Async State Hash Detection**: Uses SHA256 hashing to detect actual state changes, preventing unnecessary notifications when state values haven't truly changed
|
||||||
- **🚫 Duplicate Prevention**: Identical state updates are automatically filtered out
|
- **🚫 Duplicate Prevention**: Identical state updates are automatically filtered out
|
||||||
- **📦 Cumulative Notifications**: Batch multiple state changes into a single notification using `notifyChangeCumulative()`
|
- **📦 Cumulative Notifications**: Batch multiple state changes into a single notification using `notifyChangeCumulative()` with automatic debouncing
|
||||||
- **🎯 Selective Subscriptions**: Use selectors to subscribe only to specific state properties
|
- **🎯 Selective Subscriptions**: Use selectors to subscribe only to specific state properties
|
||||||
- **✨ Undefined State Filtering**: The `select()` method automatically filters out undefined states
|
- **✨ Undefined State Filtering**: The `select()` method automatically filters out undefined states
|
||||||
|
- **⚡ Concurrent Access Safety**: Prevents race conditions when multiple calls request the same state part simultaneously
|
||||||
|
|
||||||
### RxJS Integration
|
### RxJS Integration
|
||||||
|
|
||||||
@@ -297,6 +306,8 @@ await loginAction.trigger({ username: 'john', email: 'john@example.com' });
|
|||||||
| ✅ **Validated** | Built-in state validation with extensible validation logic |
|
| ✅ **Validated** | Built-in state validation with extensible validation logic |
|
||||||
| 🎭 **Flexible init modes** | Choose how state parts are initialized |
|
| 🎭 **Flexible init modes** | Choose how state parts are initialized |
|
||||||
| 📦 **Zero config** | Works out of the box with sensible defaults |
|
| 📦 **Zero config** | Works out of the box with sensible defaults |
|
||||||
|
| 🛡️ **Race condition safe** | Concurrent state part creation is handled safely |
|
||||||
|
| ⏱️ **Timeout support** | `waitUntilPresent` supports optional timeouts |
|
||||||
|
|
||||||
## License and Legal Information
|
## License and Legal Information
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartstate',
|
name: '@push.rocks/smartstate',
|
||||||
version: '2.0.29',
|
version: '2.0.30',
|
||||||
description: 'A package for handling and managing state in applications.'
|
description: 'A package for handling and managing state in applications.'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user