1 | import createNextState, { isDraft } from 'immer'
|
2 | import type { EntityState, PreventAny } from './models'
|
3 | import type { PayloadAction } from '../createAction'
|
4 | import { isFSA } from '../createAction'
|
5 | import { IsAny } from '../tsHelpers'
|
6 |
|
7 | export function createSingleArgumentStateOperator<V>(
|
8 | mutator: (state: EntityState<V>) => void
|
9 | ) {
|
10 | const operator = createStateOperator((_: undefined, state: EntityState<V>) =>
|
11 | mutator(state)
|
12 | )
|
13 |
|
14 | return function operation<S extends EntityState<V>>(
|
15 | state: PreventAny<S, V>
|
16 | ): S {
|
17 | return operator(state as S, undefined)
|
18 | }
|
19 | }
|
20 |
|
21 | export function createStateOperator<V, R>(
|
22 | mutator: (arg: R, state: EntityState<V>) => void
|
23 | ) {
|
24 | return function operation<S extends EntityState<V>>(
|
25 | state: S,
|
26 | arg: R | PayloadAction<R>
|
27 | ): S {
|
28 | function isPayloadActionArgument(
|
29 | arg: R | PayloadAction<R>
|
30 | ): arg is PayloadAction<R> {
|
31 | return isFSA(arg)
|
32 | }
|
33 |
|
34 | const runMutator = (draft: EntityState<V>) => {
|
35 | if (isPayloadActionArgument(arg)) {
|
36 | mutator(arg.payload, draft)
|
37 | } else {
|
38 | mutator(arg, draft)
|
39 | }
|
40 | }
|
41 |
|
42 | if (isDraft(state)) {
|
43 |
|
44 |
|
45 |
|
46 | runMutator(state)
|
47 |
|
48 |
|
49 | return state
|
50 | } else {
|
51 |
|
52 |
|
53 |
|
54 | return createNextState(state, runMutator)
|
55 | }
|
56 | }
|
57 | }
|