Skip to content

Commit df861fd

Browse files
authored
Merge pull request #3327 from EskiMojo14/more-produce
2 parents a36f092 + 9d8f344 commit df861fd

18 files changed

+626
-453
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
1-
import { current, isDraft } from 'immer'
21
import { createSelector } from 'reselect'
2+
import type { ImmutableHelpers } from './tsHelpers'
3+
import { immutableHelpers } from './immer'
4+
5+
export type BuildCreateDraftSafeSelectorConfiguration = Pick<
6+
ImmutableHelpers,
7+
'isDraft' | 'current'
8+
>
9+
10+
export function buildCreateDraftSafeSelector({
11+
isDraft,
12+
current,
13+
}: BuildCreateDraftSafeSelectorConfiguration): typeof createSelector {
14+
return function createDraftSafeSelector(...args: unknown[]) {
15+
const selector = (createSelector as any)(...args)
16+
const wrappedSelector = (value: unknown, ...rest: unknown[]) =>
17+
selector(isDraft(value) ? current(value) : value, ...rest)
18+
return wrappedSelector as any
19+
}
20+
}
321

422
/**
523
* "Draft-Safe" version of `reselect`'s `createSelector`:
@@ -8,11 +26,5 @@ import { createSelector } from 'reselect'
826
* that might be possibly outdated if the draft has been modified since.
927
* @public
1028
*/
11-
export const createDraftSafeSelector: typeof createSelector = (
12-
...args: unknown[]
13-
) => {
14-
const selector = (createSelector as any)(...args)
15-
const wrappedSelector = (value: unknown, ...rest: unknown[]) =>
16-
selector(isDraft(value) ? current(value) : value, ...rest)
17-
return wrappedSelector as any
18-
}
29+
export const createDraftSafeSelector: typeof createSelector =
30+
buildCreateDraftSafeSelector(immutableHelpers)

packages/toolkit/src/createReducer.ts

+10-23
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import type { Draft } from 'immer'
2-
import { produce as createNextState, isDraft, isDraftable } from 'immer'
32
import type { AnyAction, Action, Reducer } from 'redux'
43
import type { ActionReducerMapBuilder } from './mapBuilders'
54
import { executeReducerBuilderCallback } from './mapBuilders'
6-
import type { NoInfer } from './tsHelpers'
7-
import { makeFreezeDraftable } from './utils'
5+
import type { ImmutableHelpers, NoInfer } from './tsHelpers'
6+
import { immutableHelpers } from './immer'
87

98
/**
109
* Defines a mapping from action types to corresponding action object shapes.
@@ -153,25 +152,17 @@ const reducer = createReducer(
153152
): ReducerWithInitialState<S>
154153
}
155154

156-
export interface BuildCreateReducerConfiguration {
157-
createNextState: <Base>(
158-
base: Base,
159-
recipe: (draft: Draft<Base>) => void | Base | Draft<Base>
160-
) => Base
161-
isDraft(value: any): boolean
162-
isDraftable(value: any): boolean
163-
}
155+
export type BuildCreateReducerConfiguration = Pick<
156+
ImmutableHelpers,
157+
'createNextState' | 'isDraft' | 'isDraftable' | 'freeze'
158+
>
164159

165160
export function buildCreateReducer({
166161
createNextState,
167162
isDraft,
168163
isDraftable,
164+
freeze,
169165
}: BuildCreateReducerConfiguration): CreateReducer {
170-
const freezeDraftable = makeFreezeDraftable({
171-
createNextState,
172-
isDraft,
173-
isDraftable,
174-
})
175166
return function createReducer<S extends NotFunction<any>>(
176167
initialState: S | (() => S),
177168
mapOrBuilderCallback: (builder: ActionReducerMapBuilder<S>) => void
@@ -190,9 +181,9 @@ export function buildCreateReducer({
190181
// Ensure the initial state gets frozen either way (if draftable)
191182
let getInitialState: () => S
192183
if (isStateFunction(initialState)) {
193-
getInitialState = () => freezeDraftable(initialState())
184+
getInitialState = () => freeze(initialState(), true)
194185
} else {
195-
const frozenInitialState = freezeDraftable(initialState)
186+
const frozenInitialState = freeze(initialState, true)
196187
getInitialState = () => frozenInitialState
197188
}
198189

@@ -256,8 +247,4 @@ export function buildCreateReducer({
256247
}
257248
}
258249

259-
export const createReducer = buildCreateReducer({
260-
createNextState,
261-
isDraft,
262-
isDraftable,
263-
})
250+
export const createReducer = buildCreateReducer(immutableHelpers)

packages/toolkit/src/createSlice.ts

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { Reducer } from 'redux'
2-
import { produce as createNextState, isDraft, isDraftable } from 'immer'
32
import type {
43
ActionCreatorWithoutPayload,
54
PayloadAction,
@@ -18,7 +17,7 @@ import { buildCreateReducer } from './createReducer'
1817
import type { ActionReducerMapBuilder } from './mapBuilders'
1918
import { executeReducerBuilderCallback } from './mapBuilders'
2019
import type { NoInfer } from './tsHelpers'
21-
import { makeFreezeDraftable } from './utils'
20+
import { immutableHelpers } from './immer'
2221

2322
let hasWarnedAboutObjectNotation = false
2423

@@ -283,7 +282,7 @@ export function buildCreateSlice(
283282
configuration: BuildCreateSliceConfiguration
284283
): CreateSlice {
285284
const createReducer = buildCreateReducer(configuration)
286-
const freezeDraftable = makeFreezeDraftable(configuration)
285+
const { freeze } = configuration
287286

288287
return function createSlice<
289288
State,
@@ -311,7 +310,7 @@ export function buildCreateSlice(
311310
const initialState =
312311
typeof options.initialState == 'function'
313312
? options.initialState
314-
: freezeDraftable(options.initialState)
313+
: freeze(options.initialState)
315314

316315
const reducers = options.reducers || {}
317316

@@ -394,8 +393,4 @@ export function buildCreateSlice(
394393
}
395394
}
396395

397-
export const createSlice = buildCreateSlice({
398-
createNextState,
399-
isDraft,
400-
isDraftable,
401-
})
396+
export const createSlice = buildCreateSlice(immutableHelpers)

packages/toolkit/src/entities/create_adapter.ts

+46-29
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,56 @@ import type {
55
EntityAdapter,
66
} from './models'
77
import { createInitialStateFactory } from './entity_state'
8-
import { createSelectorsFactory } from './state_selectors'
9-
import { createSortedStateAdapter } from './sorted_state_adapter'
10-
import { createUnsortedStateAdapter } from './unsorted_state_adapter'
8+
import { buildCreateSelectorsFactory } from './state_selectors'
9+
import { buildCreateSortedStateAdapter } from './sorted_state_adapter'
10+
import { buildCreateUnsortedStateAdapter } from './unsorted_state_adapter'
11+
import type { BuildCreateDraftSafeSelectorConfiguration } from '..'
12+
import type { BuildStateOperatorConfiguration } from './state_adapter'
13+
import { immutableHelpers } from '../immer'
1114

12-
/**
13-
*
14-
* @param options
15-
*
16-
* @public
17-
*/
18-
export function createEntityAdapter<T>(
19-
options: {
15+
export interface BuildCreateEntityAdapterConfiguration
16+
extends BuildCreateDraftSafeSelectorConfiguration,
17+
BuildStateOperatorConfiguration {}
18+
19+
export type CreateEntityAdapter = {
20+
<T>(options?: {
2021
selectId?: IdSelector<T>
2122
sortComparer?: false | Comparer<T>
22-
} = {}
23-
): EntityAdapter<T> {
24-
const { selectId, sortComparer }: EntityDefinition<T> = {
25-
sortComparer: false,
26-
selectId: (instance: any) => instance.id,
27-
...options,
28-
}
23+
}): EntityAdapter<T>
24+
}
2925

30-
const stateFactory = createInitialStateFactory<T>()
31-
const selectorsFactory = createSelectorsFactory<T>()
32-
const stateAdapter = sortComparer
33-
? createSortedStateAdapter(selectId, sortComparer)
34-
: createUnsortedStateAdapter(selectId)
26+
export function buildCreateEntityAdapter(
27+
config: BuildCreateEntityAdapterConfiguration
28+
): CreateEntityAdapter {
29+
const createSelectorsFactory = buildCreateSelectorsFactory(config)
30+
const createUnsortedStateAdapter = buildCreateUnsortedStateAdapter(config)
31+
const createSortedStateAdapter = buildCreateSortedStateAdapter(config)
32+
return function createEntityAdapter<T>(
33+
options: {
34+
selectId?: IdSelector<T>
35+
sortComparer?: false | Comparer<T>
36+
} = {}
37+
): EntityAdapter<T> {
38+
const { selectId, sortComparer }: EntityDefinition<T> = {
39+
sortComparer: false,
40+
selectId: (instance: any) => instance.id,
41+
...options,
42+
}
3543

36-
return {
37-
selectId,
38-
sortComparer,
39-
...stateFactory,
40-
...selectorsFactory,
41-
...stateAdapter,
44+
const stateFactory = createInitialStateFactory<T>()
45+
const selectorsFactory = createSelectorsFactory<T>()
46+
const stateAdapter = sortComparer
47+
? createSortedStateAdapter(selectId, sortComparer)
48+
: createUnsortedStateAdapter(selectId)
49+
50+
return {
51+
selectId,
52+
sortComparer,
53+
...stateFactory,
54+
...selectorsFactory,
55+
...stateAdapter,
56+
}
4257
}
4358
}
59+
60+
export const createEntityAdapter = buildCreateEntityAdapter(immutableHelpers)

0 commit comments

Comments
 (0)