Compare commits

..

5 Commits

Author SHA1 Message Date
Juergen Kunz
09fc53aaff fix(core): Multiple fixes and improvements for version 2.0.24
Some checks failed
Default (tags) / security (push) Successful in 43s
Default (tags) / test (push) Successful in 1m1s
Default (tags) / release (push) Failing after 58s
Default (tags) / metadata (push) Successful in 1m9s
2025-07-19 08:19:59 +00:00
Juergen Kunz
bcb58dd012 chore(workspace): Add pnpm workspace configuration for built-only dependencies 2025-07-19 08:16:36 +00:00
Juergen Kunz
f0064bd94b 2.0.23
Some checks failed
Default (tags) / security (push) Successful in 46s
Default (tags) / test (push) Successful in 51s
Default (tags) / release (push) Failing after 45s
Default (tags) / metadata (push) Successful in 55s
2025-07-19 07:30:55 +00:00
Juergen Kunz
e9c527a9dc fix(ci): Update CI workflows to use new container registry and npmci package name 2025-07-19 07:30:55 +00:00
Juergen Kunz
a47d8bb3c7 fix(smartstate): Fix StateAction trigger method to properly return Promise
Some checks failed
Default (tags) / security (push) Failing after 27s
Default (tags) / test (push) Failing after 13s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-07-19 07:18:53 +00:00
9 changed files with 121 additions and 36 deletions

View File

@@ -6,8 +6,8 @@ on:
- '**'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@code.foss.global/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
@@ -26,7 +26,7 @@ jobs:
- name: Install pnpm and npmci
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
pnpm install -g @ship.zone/npmci
- name: Run npm prepare
run: npmci npm prepare

View File

@@ -6,8 +6,8 @@ on:
- '*'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@code.foss.global/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
@@ -26,7 +26,7 @@ jobs:
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Audit production dependencies
@@ -54,7 +54,7 @@ jobs:
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Test stable
@@ -82,7 +82,7 @@ jobs:
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Release
@@ -104,7 +104,7 @@ jobs:
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Code quality

View File

@@ -1,5 +1,29 @@
# Changelog
## 2025-07-19 - 2.0.24 - fix(core)
Multiple fixes and improvements
- Fixed StateAction trigger method to properly return Promise<TStateType>
- Updated CI workflows to use new container registry and npmci package name
- Added pnpm workspace configuration for built-only dependencies
## 2025-07-19 - 2.0.23 - fix(ci)
Update CI workflows to use new container registry and npmci package name
- Changed CI image from 'registry.gitlab.com/hosttoday/ht-docker-node:npmci' to 'code.foss.global/host.today/ht-docker-node:npmci'
- Replaced npmci installation command from '@shipzone/npmci' to '@ship.zone/npmci' in workflow configurations
## 2025-07-19 - 2.0.22 - fix(smartstate)
Fix StateAction trigger method to properly return Promise
- Fixed StateAction.trigger() to return Promise<TStateType> as expected
- Updated readme with improved documentation and examples
- Replaced outdated legal information with Task Venture Capital GmbH details
- Added implementation notes in readme.hints.md
## 2025-06-19 - 2.0.21 - maintenance
General updates and improvements
## 2025-06-19 - 2.0.20 - fix(smartstate)
Update build scripts and dependency versions; replace isohash with smarthashWeb for state hash generation

View File

@@ -1,6 +1,6 @@
{
"name": "@push.rocks/smartstate",
"version": "2.0.21",
"version": "2.0.24",
"private": false,
"description": "A package for handling and managing state in applications.",
"main": "dist_ts/index.js",

4
pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,4 @@
onlyBuiltDependencies:
- esbuild
- mongodb-memory-server
- puppeteer

View File

@@ -1 +1,39 @@
# Smartstate Implementation Notes
## Current API (as of analysis)
### State Part Initialization
- State parts can be created with different init modes: 'soft', 'mandatory', 'force', 'persistent'
- Persistent mode automatically calls init() internally - no need to call it manually
- WebStore integration for persistent state uses IndexedDB
### Actions
- Actions are created with `createAction()` method
- Two ways to dispatch actions:
1. `stateAction.trigger(payload)` - returns Promise<TStatePayload>
2. `await statePart.dispatchAction(stateAction, payload)` - returns Promise<TStatePayload>
- Both methods now return the same Promise, providing flexibility in usage
### State Management Methods
- `select()` - returns Observable with startWith current state
- `waitUntilPresent()` - waits for specific state condition
- `stateSetup()` - async state initialization with cumulative defer
- `notifyChangeCumulative()` - defers notification to end of call stack (no callback parameter)
### State Hash Detection
- Uses SHA256 hash to detect actual state changes
- Bug: Currently stores the state object itself as hash instead of the actual hash
- This prevents proper duplicate notification prevention
### Type System
- Can use either enums or string literal types for state part names
- Test uses simple string types: `type TMyStateParts = 'testStatePart'`
## Fixed Issues in Documentation
1. Updated trigger() to return Promise (API enhancement)
2. Added dispatchAction as alternative method
3. Corrected notifyChangeCumulative usage
4. Clarified persistent mode auto-init
5. Added stateSetup documentation
6. Fixed state hash detection description
7. Both trigger() and dispatchAction() now return Promise for consistency

View File

@@ -1,5 +1,5 @@
# @push.rocks/smartstate
a package that handles state in a good way
A package for handling and managing state in applications
## Install
@@ -44,13 +44,17 @@ When creating state parts, you can specify different initialization modes:
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.
Define an enum for state part names for better management:
Define state part names using either enums or string literal types:
```typescript
// Option 1: Using enums
enum AppStateParts {
UserState,
SettingsState
UserState = 'UserState',
SettingsState = 'SettingsState'
}
// Option 2: Using string literal types (simpler approach)
type AppStateParts = 'UserState' | 'SettingsState';
```
Now, let's create a state part within our `myAppSmartState` instance:
@@ -67,10 +71,7 @@ const userStatePart = await myAppSmartState.getStatePart<IUserState>(
'soft' // Init mode (optional, defaults to 'soft')
);
// For persistent state parts, you must call init()
if (mode === 'persistent') {
await userStatePart.init();
}
// Note: Persistent state parts are automatically initialized internally
```
### Subscribing to State Changes
@@ -107,9 +108,27 @@ const loginUserAction = userStatePart.createAction<ILoginPayload>(async (statePa
});
// Dispatch the action to update the state
await loginUserAction.trigger({ username: 'johnDoe' });
loginUserAction.trigger({ username: 'johnDoe' });
// or await the result
const newState = await loginUserAction.trigger({ username: 'johnDoe' });
```
### Dispatching Actions
There are two ways to dispatch actions:
```typescript
// Method 1: Using trigger on the action (returns promise)
const newState = await loginUserAction.trigger({ username: 'johnDoe' });
// or fire and forget
loginUserAction.trigger({ username: 'johnDoe' });
// Method 2: Using dispatchAction on the state part (returns promise)
const newState = await userStatePart.dispatchAction(loginUserAction, { username: 'johnDoe' });
```
Both methods return a Promise with the new state, giving you flexibility in how you handle the result.
### Additional State Methods
`StatePart` provides several useful methods for state management:
@@ -118,17 +137,18 @@ await loginUserAction.trigger({ username: 'johnDoe' });
// Wait for a specific state condition
await userStatePart.waitUntilPresent();
// Wait for a specific property to be present
await userStatePart.waitUntilPresent(state => state.username);
// Setup initial state with async operations
await userStatePart.stateSetup(async (state) => {
await userStatePart.stateSetup(async (statePart) => {
// Perform async initialization
const userData = await fetchUserData();
return { ...state, ...userData };
return { ...statePart.getState(), ...userData };
});
// Batch multiple state changes for cumulative notification
userStatePart.notifyChangeCumulative(() => {
// Multiple state changes here will result in a single notification
});
// Defer notification to end of call stack
userStatePart.notifyChangeCumulative();
```
### Persistent State with WebStore
@@ -142,8 +162,7 @@ const settingsStatePart = await myAppSmartState.getStatePart<ISettingsState>(
'persistent' // Mode
);
// Initialize the persistent state (required for persistent mode)
await settingsStatePart.init();
// Note: init() is called automatically for persistent mode
```
Persistent state automatically:
@@ -155,7 +174,7 @@ Persistent state automatically:
`Smartstate` includes built-in performance optimizations:
- **State Hash Detection**: Uses SHA256 hashing to detect actual state changes, preventing unnecessary notifications when state values haven't truly changed
- **State Change Detection**: Detects actual state changes to prevent unnecessary notifications when state values haven't truly changed
- **Cumulative Notifications**: Batch multiple state changes into a single notification using `notifyChangeCumulative()`
- **Selective Subscriptions**: Use selectors to subscribe only to specific state properties
@@ -205,13 +224,13 @@ This repository contains open-source code that is licensed under the MIT License
### Trademarks
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.
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.
### Company Information
Lossless GmbH
Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require further information, please contact us via email at hello@lossless.com.
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
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.
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.

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartstate',
version: '2.0.20',
version: '2.0.23',
description: 'A package for handling and managing state in applications.'
}

View File

@@ -14,7 +14,7 @@ export class StateAction<TStateType, TActionPayloadType> {
public actionDef: IActionDef<TStateType, TActionPayloadType>
) {}
public trigger(payload: TActionPayloadType) {
this.statePartRef.dispatchAction(this, payload);
public trigger(payload: TActionPayloadType): Promise<TStateType> {
return this.statePartRef.dispatchAction(this, payload);
}
}