Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: configurable produce implementation #3074

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
49f808a
allow `produce` to be swapped out in createReducer/createSlice
phryneas Jan 11, 2023
f0228f9
Make more Immer utils configurable
markerikson Feb 21, 2023
fb9d324
add buildable createDraftSafeSelector
Apr 4, 2023
293a9b9
make configurable createEntityAdapter
Apr 4, 2023
83a8931
unused type
Apr 4, 2023
411568a
declare immutable helper types once
Apr 4, 2023
d9e1341
build createDraftSafeSelector outside of createSelectorsFactory
Apr 4, 2023
e5f48f1
allow replacing RTKQ's usage of immer
Apr 5, 2023
4f6c897
use immutablehelpers for RTKQ's createSlice
Apr 5, 2023
28a87c9
named export instead of default
Apr 5, 2023
180d198
use specific freeze function instead of abusing createNextState
Apr 5, 2023
5bd963c
export buildCreateEntityAdapter
Apr 5, 2023
bc924e7
Merge branch 'v2.0-integration' into more-produce
Apr 5, 2023
9f9dfff
export ImmutableHelpers
Apr 5, 2023
a36f092
Merge branch 'v2.0-integration' into pr/configure-produce-implementation
Apr 5, 2023
27bcf3b
Merge branch 'pr/configure-produce-implementation' into more-produce
Apr 5, 2023
19d5b8d
create a defineImmutableHelpers identity function, and use for immer
Apr 5, 2023
9614298
don't use @internal import
Apr 5, 2023
7eb1fa0
import ImmutableHelpers type from RTK
Apr 5, 2023
115b856
fix entity adapter options not being optional
Apr 18, 2023
bfa1419
hope the PR gets happier
May 5, 2023
9d8f344
be extra assertive about nicking reselect's types
May 5, 2023
df861fd
Merge pull request #3327 from EskiMojo14/more-produce
markerikson May 5, 2023
080974d
Merge branch 'v2.0-integration' into pr/configure-produce-implementation
May 16, 2023
30b1b49
Merge branch 'v2.0-integration' into pr/configure-produce-implementation
EskiMojo14 May 29, 2023
7276087
Merge branch 'v2.0-integration' into pr/configure-produce-implementation
Oct 2, 2023
b43f501
rtkImports
Oct 2, 2023
0888fde
add missing createEntityAdapter overload
Oct 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
create a defineImmutableHelpers identity function, and use for immer
  • Loading branch information
ben.durrant committed Apr 5, 2023
commit 19d5b8de65f9c53616e47b3ecd14059d47ba36ab
8 changes: 3 additions & 5 deletions packages/toolkit/src/createDraftSafeSelector.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { current, isDraft } from 'immer'
import { createSelector } from 'reselect'
import type { ImmutableHelpers } from './tsHelpers'
import { immutableHelpers } from './immer'

export type BuildCreateDraftSafeSelectorConfiguration = Pick<
ImmutableHelpers,
Expand Down Expand Up @@ -28,7 +28,5 @@ export function buildCreateDraftSafeSelector({
}
}

export const createDraftSafeSelector = buildCreateDraftSafeSelector({
isDraft,
current,
})
export const createDraftSafeSelector =
buildCreateDraftSafeSelector(immutableHelpers)
9 changes: 2 additions & 7 deletions packages/toolkit/src/createReducer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Draft } from 'immer'
import { produce as createNextState, isDraft, freeze, isDraftable } from 'immer'
import type { AnyAction, Action, Reducer } from 'redux'
import type { ActionReducerMapBuilder } from './mapBuilders'
import { executeReducerBuilderCallback } from './mapBuilders'
import type { ImmutableHelpers, NoInfer } from './tsHelpers'
import { immutableHelpers } from './immer'

/**
* Defines a mapping from action types to corresponding action object shapes.
Expand Down Expand Up @@ -247,9 +247,4 @@ export function buildCreateReducer({
}
}

export const createReducer = buildCreateReducer({
createNextState,
isDraft,
isDraftable,
freeze,
})
export const createReducer = buildCreateReducer(immutableHelpers)
9 changes: 2 additions & 7 deletions packages/toolkit/src/createSlice.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Reducer } from 'redux'
import { produce as createNextState, freeze, isDraft, isDraftable } from 'immer'
import type {
ActionCreatorWithoutPayload,
PayloadAction,
Expand All @@ -18,6 +17,7 @@ import { buildCreateReducer } from './createReducer'
import type { ActionReducerMapBuilder } from './mapBuilders'
import { executeReducerBuilderCallback } from './mapBuilders'
import type { NoInfer } from './tsHelpers'
import { immutableHelpers } from './immer'

let hasWarnedAboutObjectNotation = false

Expand Down Expand Up @@ -393,9 +393,4 @@ export function buildCreateSlice(
}
}

export const createSlice = buildCreateSlice({
createNextState,
isDraft,
isDraftable,
freeze,
})
export const createSlice = buildCreateSlice(immutableHelpers)
8 changes: 2 additions & 6 deletions packages/toolkit/src/entities/create_adapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { isDraft, current, produce as createNextState } from 'immer'
import type {
EntityDefinition,
Comparer,
Expand All @@ -11,6 +10,7 @@ import { buildCreateSortedStateAdapter } from './sorted_state_adapter'
import { buildCreateUnsortedStateAdapter } from './unsorted_state_adapter'
import type { BuildCreateDraftSafeSelectorConfiguration } from '..'
import type { BuildStateOperatorConfiguration } from './state_adapter'
import { immutableHelpers } from '@internal/immer'

export interface BuildCreateEntityAdapterConfiguration
extends BuildCreateDraftSafeSelectorConfiguration,
Expand Down Expand Up @@ -57,8 +57,4 @@ export function buildCreateEntityAdapter(
}
}

export const createEntityAdapter = buildCreateEntityAdapter({
isDraft,
current,
createNextState,
})
export const createEntityAdapter = buildCreateEntityAdapter(immutableHelpers)
22 changes: 22 additions & 0 deletions packages/toolkit/src/immer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
applyPatches,
current,
freeze,
isDraft,
isDraftable,
original,
produce,
produceWithPatches,
} from 'immer'
import { defineImmutableHelpers } from './tsHelpers'

export const immutableHelpers = defineImmutableHelpers({
createNextState: produce,
createWithPatches: produceWithPatches,
applyPatches,
isDraft,
isDraftable,
original,
current,
freeze,
})
2 changes: 2 additions & 0 deletions packages/toolkit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,5 @@ export {
export type { AutoBatchOptions } from './autoBatchEnhancer'

export type { ImmutableHelpers } from './tsHelpers'
export { defineImmutableHelpers } from './tsHelpers'
export { immutableHelpers as immerImmutableHelpers } from './immer'
20 changes: 3 additions & 17 deletions packages/toolkit/src/query/core/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
ThunkAction,
ThunkDispatch,
} from '@reduxjs/toolkit'
import { immerImmutableHelpers } from '@reduxjs/toolkit'
import type {
EndpointDefinitions,
QueryArgFrom,
Expand Down Expand Up @@ -50,15 +51,7 @@ import type { BaseQueryFn } from '../baseQueryTypes'
import type { ReferenceCacheLifecycle } from './buildMiddleware/cacheLifecycle'
import type { ReferenceQueryLifecycle } from './buildMiddleware/queryLifecycle'
import type { ReferenceCacheCollection } from './buildMiddleware/cacheCollection'
import {
produce,
applyPatches,
enablePatches,
isDraft,
isDraftable,
produceWithPatches,
freeze,
} from 'immer'
import { enablePatches } from 'immer'

/**
* `ifOlderThan` - (default: `false` | `number`) - _number is value in seconds_
Expand Down Expand Up @@ -478,14 +471,7 @@ interface CoreModuleOptions {
* ```
*/
export const coreModule = ({
immutableHelpers = {
createNextState: produce,
createWithPatches: produceWithPatches,
applyPatches,
isDraft,
isDraftable,
freeze,
},
immutableHelpers = immerImmutableHelpers,
}: CoreModuleOptions = {}): Module<CoreModule> => ({
name: coreModuleName,
init(
Expand Down
35 changes: 34 additions & 1 deletion packages/toolkit/src/tsHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,56 @@ import type { Draft, Patch, applyPatches } from 'immer'
import type { MiddlewareArray } from './utils'

export interface ImmutableHelpers {
/**
* Function that receives a base object, and a recipe which is called with a draft that the recipe is allowed to mutate.
* The recipe can return a new state which will replace the existing state, or it can not return (in which case the existing draft is used)
* Returns an immutably modified version of the input object.
*/
createNextState: <Base>(
base: Base,
recipe: (draft: Draft<Base>) => void | Base | Draft<Base>
) => Base
/**
* Function that receives a base object, and a recipe which is called with a draft that the recipe is allowed to mutate.
* The recipe can return a new state which will replace the existing state, or it can not return (in which case the existing draft is used)
* Returns a tuple of an immutably modified version of the input object, an array of patches describing the changes made, and an array of inverse patches.
*/
createWithPatches: <Base>(
base: Base,
recipe: (draft: Draft<Base>) => void | Base | Draft<Base>
) => readonly [Base, Patch[], Patch[]]
// depends on an Objectish type that immer doesn't export
/**
* Receives a base object and an array of patches describing changes to apply.
* Returns an immutably modified version of the base object with changes applied.
*/
applyPatches: typeof applyPatches
/**
* Indicates whether the value passed is a draft, meaning it's safe to mutate.
*/
isDraft(value: any): boolean
/**
* Indicates whether the value passed is possible to turn into a mutable draft.
*/
isDraftable(value: any): boolean
/**
* Receives a draft and returns its base object.
*/
original<T>(value: T): T | undefined
/**
* Receives a draft and returns an object with any changes to date immutably applied.
*/
current<T>(value: T): T
/**
* Receives an object and freezes it, causing runtime errors if mutation is attempted after.
*/
freeze<T>(obj: T, deep?: boolean): T
}

/**
* Define a config object indicating utilities for RTK packages to use for immutable operations.
*/
export const defineImmutableHelpers = (helpers: ImmutableHelpers) => helpers

/**
* return True if T is `any`, otherwise return False
* taken from https://github.com/joonhocho/tsdef
Expand Down