Skip to content

Commit

Permalink
refactor: add improvements according to review.
Browse files Browse the repository at this point in the history
  • Loading branch information
rainerhahnekamp committed Mar 12, 2024
1 parent 6d68366 commit f7a2b51
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 22 deletions.
39 changes: 19 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,24 @@ export class MoviesStore extends ImmerComponentStore<MoviesState> {
Provides an Immer-version of the `patchState` function from the `@ngrx/signals` package. In addition to partial state objects and updaters that update the state immutably, it accepts updater functions that update the state in a mutable manner. Similar to `patchState`, the `immerPatchState` function can be used to update the state of both SignalStore and SignalState.

```ts
const UserState = signalStore(
withState({
id: 1,
name: { firstname: 'Konrad', lastname: 'Schultz' },
address: { city: 'Vienna', zip: '1010' },
}),
withComputed(({ name }) => ({
prettyName: computed(() => `${name.firstname()} ${name.lastname()}`),
}))
const UserStore = signalStore(
withState({
user: { firstName: 'Konrad', lastName: 'Schultz' },
address: { city: 'Vienna', zip: '1010' },
}),
withMethods((store) => ({
setLastName(lastName: string): void {
immerPatchState(store, (state) => {
state.user.lastName = lastName;
});
},
setCity(city: string): void {
immerPatchState(store, (state) => {
state.address.city = city;
});
},
}))
);

const userState = new UserState();

immerPatchState(userState, (state => {
state.name = { firstname: 'Lucy', lastname: 'Sanders' };
state.address.zip = '1020'
}));
```

Please note, that the updater function can only mutate a change without returning it or return an immutable
Expand All @@ -112,13 +113,11 @@ This one is going to throw a runtime error:
```ts
// will throw because of both returning and mutable change
immerPatchState(userStore, (state) => {
state.name.lastname = 'Sanders'; // mutable change
return state; // returning state
state.name.lastname = 'Sanders'; // mutable change
return state; // returning state
});
```



## `immerReducer`

Inspired by [Alex Okrushko](https://twitter.com/alexokrushko), `immerReducer` is a reducer method that uses the Immer `produce` method.
Expand Down
4 changes: 2 additions & 2 deletions src/signals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { immerReducer } from 'ngrx-immer';

export type ImmerStateUpdater<State extends object> = (state: State) => void;

function toFullStateUpdater<State extends object>(updater: PartialStateUpdater<State & {}> | MutableStateUpdater<State & {}>): (state: State) => State | void {
function toFullStateUpdater<State extends object>(updater: PartialStateUpdater<State & {}> | ImmerStateUpdater<State & {}>): (state: State) => State | void {
return (state: State) => {
const patchedState = updater(state);
if (patchedState) {
Expand All @@ -13,7 +13,7 @@ function toFullStateUpdater<State extends object>(updater: PartialStateUpdater<S
};
}

export function immerPatchState<State extends object>(state: StateSignal<State>, ...updaters: Array<Partial<State & {}> | PartialStateUpdater<State & {}> | MutableStateUpdater<State & {}>>) {
export function immerPatchState<State extends object>(state: StateSignal<State>, ...updaters: Array<Partial<State & {}> | PartialStateUpdater<State & {}> | ImmerStateUpdater<State & {}>>) {
const immerUpdaters = updaters.map(updater => {
if (typeof updater === 'function') {
return immerReducer(toFullStateUpdater(updater)) as unknown as PartialStateUpdater<State & {}>;
Expand Down

0 comments on commit f7a2b51

Please sign in to comment.