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
Merge branch 'v2.0-integration' into pr/configure-produce-implementation
  • Loading branch information
EskiMojo14 committed May 29, 2023
commit 30b1b49c50812c913cc8809672c810b370913b03
18 changes: 9 additions & 9 deletions packages/toolkit/src/entities/create_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export interface BuildCreateEntityAdapterConfiguration
BuildStateOperatorConfiguration {}

export type CreateEntityAdapter = {
<T>(options?: {
selectId?: IdSelector<T>
<T, Id extends EntityId>(options?: {
selectId?: IdSelector<T, Id>
sortComparer?: false | Comparer<T>
}): EntityAdapter<T>
}): EntityAdapter<T, Id>
}

export function buildCreateEntityAdapter(
Expand All @@ -30,20 +30,20 @@ export function buildCreateEntityAdapter(
const createSelectorsFactory = buildCreateSelectorsFactory(config)
const createUnsortedStateAdapter = buildCreateUnsortedStateAdapter(config)
const createSortedStateAdapter = buildCreateSortedStateAdapter(config)
return function createEntityAdapter<T>(
return function createEntityAdapter<T, Id extends EntityId>(
options: {
selectId?: IdSelector<T>
selectId?: IdSelector<T, Id>
sortComparer?: false | Comparer<T>
} = {}
): EntityAdapter<T> {
const { selectId, sortComparer }: EntityDefinition<T> = {
): EntityAdapter<T, Id> {
const { selectId, sortComparer }: EntityDefinition<T, Id> = {
sortComparer: false,
selectId: (instance: any) => instance.id,
...options,
}

const stateFactory = createInitialStateFactory<T>()
const selectorsFactory = createSelectorsFactory<T>()
const stateFactory = createInitialStateFactory<T, Id>()
const selectorsFactory = createSelectorsFactory<T, Id>()
const stateAdapter = sortComparer
? createSortedStateAdapter(selectId, sortComparer)
: createUnsortedStateAdapter(selectId)
Expand Down
22 changes: 11 additions & 11 deletions packages/toolkit/src/entities/sorted_state_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export function buildCreateSortedStateAdapter(
) {
const createUnsortedStateAdapter = buildCreateUnsortedStateAdapter(config)
const createStateOperator = buildCreateStateOperator(config)
return function createSortedStateAdapter<T>(
selectId: IdSelector<T>,
return function createSortedStateAdapter<T, Id extends EntityId>(
selectId: IdSelector<T, Id>,
sort: Comparer<T>
): EntityStateAdapter<T> {
type R = EntityState<T>
): EntityStateAdapter<T, Id> {
type R = EntityState<T, Id>

const { removeOne, removeMany, removeAll } =
createUnsortedStateAdapter(selectId)
Expand All @@ -34,7 +34,7 @@ export function buildCreateSortedStateAdapter(
}

function addManyMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
newEntities = ensureEntitiesArray(newEntities)
Expand All @@ -53,7 +53,7 @@ export function buildCreateSortedStateAdapter(
}

function setManyMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
newEntities = ensureEntitiesArray(newEntities)
Expand All @@ -63,7 +63,7 @@ export function buildCreateSortedStateAdapter(
}

function setAllMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
newEntities = ensureEntitiesArray(newEntities)
Expand All @@ -73,12 +73,12 @@ export function buildCreateSortedStateAdapter(
addManyMutably(newEntities, state)
}

function updateOneMutably(update: Update<T>, state: R): void {
function updateOneMutably(update: Update<T, Id>, state: R): void {
return updateManyMutably([update], state)
}

function updateManyMutably(
updates: ReadonlyArray<Update<T>>,
updates: ReadonlyArray<Update<T, Id>>,
state: R
): void {
let appliedUpdates = false
Expand Down Expand Up @@ -109,10 +109,10 @@ export function buildCreateSortedStateAdapter(
}

function upsertManyMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
const [added, updated] = splitAddedUpdatedEntities<T>(
const [added, updated] = splitAddedUpdatedEntities<T, Id>(
newEntities,
selectId,
state
Expand Down
21 changes: 10 additions & 11 deletions packages/toolkit/src/entities/state_adapter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { EntityState, PreventAny } from './models'
import type { EntityId, EntityState, PreventAny } from './models'
import type { PayloadAction } from '../createAction'
import { isFSA } from '../createAction'
import type { ImmutableHelpers } from '../tsHelpers'
import { IsAny } from '../tsHelpers'

export type BuildStateOperatorConfiguration = Pick<
ImmutableHelpers,
Expand All @@ -13,15 +12,15 @@ export function buildCreateSingleArgumentStateOperator(
config: BuildStateOperatorConfiguration
) {
const createStateOperator = buildCreateStateOperator(config)
return function createSingleArgumentStateOperator<V>(
mutator: (state: EntityState<V>) => void
return function createSingleArgumentStateOperator<V, Id extends EntityId>(
mutator: (state: EntityState<V, Id>) => void
) {
const operator = createStateOperator(
(_: undefined, state: EntityState<V>) => mutator(state)
(_: undefined, state: EntityState<V, Id>) => mutator(state)
)

return function operation<S extends EntityState<V>>(
state: PreventAny<S, V>
return function operation<S extends EntityState<V, Id>>(
state: PreventAny<S, V, Id>
): S {
return operator(state as S, undefined)
}
Expand All @@ -32,10 +31,10 @@ export function buildCreateStateOperator({
isDraft,
createNextState,
}: BuildStateOperatorConfiguration) {
return function createStateOperator<V, R>(
mutator: (arg: R, state: EntityState<V>) => void
return function createStateOperator<V, Id extends EntityId, R>(
mutator: (arg: R, state: EntityState<V, Id>) => void
) {
return function operation<S extends EntityState<V>>(
return function operation<S extends EntityState<V, Id>>(
state: S,
arg: R | PayloadAction<R>
): S {
Expand All @@ -45,7 +44,7 @@ export function buildCreateStateOperator({
return isFSA(arg)
}

const runMutator = (draft: EntityState<V>) => {
const runMutator = (draft: EntityState<V, Id>) => {
if (isPayloadActionArgument(arg)) {
mutator(arg.payload, draft)
} else {
Expand Down
23 changes: 11 additions & 12 deletions packages/toolkit/src/entities/state_selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,27 @@ export function buildCreateSelectorsFactory(
) {
const createDraftSafeSelector = buildCreateDraftSafeSelector(config)

return function createSelectorsFactory<T>() {
function getSelectors(): EntitySelectors<T, EntityState<T>>
return function createSelectorsFactory<T, Id extends EntityId>() {
function getSelectors(): EntitySelectors<T, EntityState<T, Id>, Id>
function getSelectors<V>(
selectState: (state: V) => EntityState<T>
): EntitySelectors<T, V>
selectState: (state: V) => EntityState<T, Id>
): EntitySelectors<T, V, Id>
function getSelectors<V>(
selectState?: (state: V) => EntityState<T>
): EntitySelectors<T, any> {
const selectIds = (state: EntityState<T>) => state.ids
selectState?: (state: V) => EntityState<T, Id>
): EntitySelectors<T, any, Id> {
const selectIds = (state: EntityState<T, Id>) => state.ids

const selectEntities = (state: EntityState<T>) => state.entities
const selectEntities = (state: EntityState<T, Id>) => state.entities

const selectAll = createDraftSafeSelector(
selectIds,
selectEntities,
(ids, entities): T[] => ids.map((id) => entities[id]!)
)

const selectId = (_: unknown, id: EntityId) => id

const selectById = (entities: Dictionary<T>, id: EntityId) => entities[id]
const selectId = (_: unknown, id: Id) => id

const selectById = (entities: Dictionary<T, Id>, id: Id) => entities[id]
const selectTotal = createDraftSafeSelector(
selectIds,
(ids) => ids.length
Expand All @@ -55,7 +54,7 @@ export function buildCreateSelectorsFactory(
}

const selectGlobalizedEntities = createDraftSafeSelector(
selectState as Selector<V, EntityState<T>>,
selectState as Selector<V, EntityState<T, Id>>,
selectEntities
)

Expand Down
40 changes: 21 additions & 19 deletions packages/toolkit/src/entities/unsorted_state_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ export function buildCreateUnsortedStateAdapter(
const createSingleArgumentStateOperator =
buildCreateSingleArgumentStateOperator(config)
const createStateOperator = buildCreateStateOperator(config)
return function createUnsortedStateAdapter<T>(
selectId: IdSelector<T>
): EntityStateAdapter<T> {
type R = EntityState<T>
return function createUnsortedStateAdapter<T, Id extends EntityId>(
selectId: IdSelector<T, Id>
): EntityStateAdapter<T, Id> {
type R = EntityState<T, Id>

function addOneMutably(entity: T, state: R): void {
const key = selectIdValue(entity, selectId)
Expand All @@ -39,7 +39,7 @@ export function buildCreateUnsortedStateAdapter(
}

function addManyMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
newEntities = ensureEntitiesArray(newEntities)
Expand All @@ -58,7 +58,7 @@ export function buildCreateUnsortedStateAdapter(
}

function setManyMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
newEntities = ensureEntitiesArray(newEntities)
Expand All @@ -68,7 +68,7 @@ export function buildCreateUnsortedStateAdapter(
}

function setAllMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
newEntities = ensureEntitiesArray(newEntities)
Expand All @@ -79,11 +79,11 @@ export function buildCreateUnsortedStateAdapter(
addManyMutably(newEntities, state)
}

function removeOneMutably(key: EntityId, state: R): void {
function removeOneMutably(key: Id, state: R): void {
return removeManyMutably([key], state)
}

function removeManyMutably(keys: readonly EntityId[], state: R): void {
function removeManyMutably(keys: readonly Id[], state: R): void {
let didMutate = false

keys.forEach((key) => {
Expand All @@ -106,11 +106,11 @@ export function buildCreateUnsortedStateAdapter(
}

function takeNewKey(
keys: { [id: string]: EntityId },
update: Update<T>,
keys: { [id: string]: Id },
update: Update<T, Id>,
state: R
): boolean {
const original = state.entities[update.id]
const original: T | undefined = state.entities[update.id]
const updated: T = Object.assign({}, original, update.changes)
const newKey = selectIdValue(updated, selectId)
const hasNewKey = newKey !== update.id
Expand All @@ -125,17 +125,17 @@ export function buildCreateUnsortedStateAdapter(
return hasNewKey
}

function updateOneMutably(update: Update<T>, state: R): void {
function updateOneMutably(update: Update<T, Id>, state: R): void {
return updateManyMutably([update], state)
}

function updateManyMutably(
updates: ReadonlyArray<Update<T>>,
updates: ReadonlyArray<Update<T, Id>>,
state: R
): void {
const newKeys: { [id: string]: EntityId } = {}
const newKeys: { [id: string]: Id } = {}

const updatesPerEntity: { [id: string]: Update<T> } = {}
const updatesPerEntity: { [id: string]: Update<T, Id> } = {}

updates.forEach((update) => {
// Only apply updates to entities that currently exist
Expand Down Expand Up @@ -165,7 +165,9 @@ export function buildCreateUnsortedStateAdapter(
.length > 0

if (didMutateIds) {
state.ids = Object.keys(state.entities)
state.ids = Object.values(state.entities).map((e) =>
selectIdValue(e as T, selectId)
)
}
}
}
Expand All @@ -175,10 +177,10 @@ export function buildCreateUnsortedStateAdapter(
}

function upsertManyMutably(
newEntities: readonly T[] | Record<EntityId, T>,
newEntities: readonly T[] | Record<Id, T>,
state: R
): void {
const [added, updated] = splitAddedUpdatedEntities<T>(
const [added, updated] = splitAddedUpdatedEntities<T, Id>(
newEntities,
selectId,
state
Expand Down
2 changes: 1 addition & 1 deletion packages/toolkit/src/tsHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Middleware, StoreEnhancer } from 'redux'
import type { Draft, Patch, applyPatches } from 'immer'
import type { EnhancerArray, MiddlewareArray } from './utils'
import type { Tuple } from './utils'

export function safeAssign<T extends object>(
target: T,
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.