You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor!: split up state signal to multiple signals
This is a necessary refactoring to support a state which allows different types of Signals, i.e. `linkedSignal` & `signal` but still presents itself as a single unit to the outside.
This commit splits the single Signal of `STATE_SOURCE`, which contains the state in the `SignalStore` and `signalState`, into multiple Signals.
An example. Given the following type:
```typescript
type User = {
firstname: string;
lastname: string;
};
```
Before, `STATE_SOURCE` would have been the following type:
```typescript
WritableSignal<User>;
```
With this change, it is:
```typescript
{
firstname: WritableSignal<string>;
lastname: WritableSignal<string>;
}
```
Most changes affect the tests which focus on the `STATE_SOURCE`. Except for one test in `signal-state.spec.ts` ('does not modify STATE_SOURCE'), all tests could be updated to assert the new behavior.
## Breaking Changes
- Any code which accesses the hidden `STATE_SOURCE` will be impacted.
- Breaking Changes to the public behavior are rare.
### different object reference for state of `STATE_SOURCE`
`STATE_SOURCE` does not keep the object reference of the initial state upon initialization.
```typescript
const initialObject = {
ngrx: 'rocks',
};
const state = signalState(initialObject);
// before
state() === initialObject; // ✅
// after
state() === initialObject; // ❌
```
### no Signal change on empty patched state
`patchState` created a clone of the state and applied the patches to the clone. That meant, if nothing was changed, the Signal still fired because of the shallow clone. Since the state Signal doesn't exist anymore, there will be no change in this case.
```typescript
const state = signalState({ ngrx: 'rocks' });
let changeCount = 0;
effect(() => {
changeCount++;
});
TestBed.flushEffects();
expect(changeCount).toBe(1);
patchState(state, {});
// before
expect(changeCount).toBe(2); // ✅
// after
expect(changeCount).toBe(2); // ❌ changeCount is still 1
```
## Further Changes
- `signalStoreFeature` had to be refactored because of typing issues with the change to `WritableStateSource`.
- `patchState` get the `NoInfer` for `updaters` argument. Otherwise, with multiple updaters, the former updater would have defined the `State` for the next updater.
0 commit comments