From edf9c11dd398a6d9cea021949c3ce499c8cc9635 Mon Sep 17 00:00:00 2001 From: EskiMojo14 Date: Sun, 11 Feb 2024 17:02:31 +0000 Subject: [PATCH 1/4] Add second parameter to getInitialState to prefill entities --- .../toolkit/src/entities/create_adapter.ts | 4 +-- packages/toolkit/src/entities/entity_state.ts | 27 +++++++++++++++---- packages/toolkit/src/entities/models.ts | 16 ++++++++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/toolkit/src/entities/create_adapter.ts b/packages/toolkit/src/entities/create_adapter.ts index 726ad82c32..caddffb765 100644 --- a/packages/toolkit/src/entities/create_adapter.ts +++ b/packages/toolkit/src/entities/create_adapter.ts @@ -42,11 +42,11 @@ export function createEntityAdapter( ...options, } - const stateFactory = createInitialStateFactory() - const selectorsFactory = createSelectorsFactory() const stateAdapter = sortComparer ? createSortedStateAdapter(selectId, sortComparer) : createUnsortedStateAdapter(selectId) + const stateFactory = createInitialStateFactory({ stateAdapter }) + const selectorsFactory = createSelectorsFactory() return { selectId, diff --git a/packages/toolkit/src/entities/entity_state.ts b/packages/toolkit/src/entities/entity_state.ts index 6b0744cdee..f235f8c7d2 100644 --- a/packages/toolkit/src/entities/entity_state.ts +++ b/packages/toolkit/src/entities/entity_state.ts @@ -1,4 +1,9 @@ -import type { EntityId, EntityState } from './models' +import type { + EntityId, + EntityState, + EntityStateAdapter, + EntityStateFactory, +} from './models' export function getInitialEntityState(): EntityState< T, @@ -10,13 +15,25 @@ export function getInitialEntityState(): EntityState< } } -export function createInitialStateFactory() { - function getInitialState(): EntityState +export function createInitialStateFactory({ + stateAdapter, +}: { + stateAdapter: EntityStateAdapter +}): EntityStateFactory { + function getInitialState( + state?: undefined, + entities?: readonly T[] | Record, + ): EntityState function getInitialState( additionalState: S, + entities?: readonly T[] | Record, ): EntityState & S - function getInitialState(additionalState: any = {}): any { - return Object.assign(getInitialEntityState(), additionalState) + function getInitialState( + additionalState: any = {}, + entities?: readonly T[] | Record, + ): any { + const state = Object.assign(getInitialEntityState(), additionalState) + return entities ? stateAdapter.setAll(state, entities) : state } return { getInitialState } diff --git a/packages/toolkit/src/entities/models.ts b/packages/toolkit/src/entities/models.ts index a7ec0238d9..02cc01701e 100644 --- a/packages/toolkit/src/entities/models.ts +++ b/packages/toolkit/src/entities/models.ts @@ -166,15 +166,25 @@ export interface EntitySelectors { selectById: (state: V, id: Id) => Compute> } +export interface EntityStateFactory { + getInitialState( + state?: undefined, + entities?: Record | readonly T[], + ): EntityState + getInitialState( + state: S, + entities?: Record | readonly T[], + ): EntityState & S +} + /** * @public */ export interface EntityAdapter - extends EntityStateAdapter { + extends EntityStateAdapter, + EntityStateFactory { selectId: IdSelector sortComparer: false | Comparer - getInitialState(): EntityState - getInitialState(state: S): EntityState & S getSelectors( selectState?: undefined, options?: GetSelectorsOptions, From 244b3e324d706a751258877cc7dd159a6c4b53a0 Mon Sep 17 00:00:00 2001 From: EskiMojo14 Date: Sun, 11 Feb 2024 17:19:43 +0000 Subject: [PATCH 2/4] tweak types --- .../toolkit/src/entities/create_adapter.ts | 37 +++++++------------ packages/toolkit/src/entities/models.ts | 14 ++++--- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/packages/toolkit/src/entities/create_adapter.ts b/packages/toolkit/src/entities/create_adapter.ts index caddffb765..0dc936c704 100644 --- a/packages/toolkit/src/entities/create_adapter.ts +++ b/packages/toolkit/src/entities/create_adapter.ts @@ -1,28 +1,17 @@ -import type { - EntityDefinition, - Comparer, - IdSelector, - EntityAdapter, - EntityId, -} from './models' +import type { EntityAdapter, EntityId, EntityAdapterOptions } from './models' import { createInitialStateFactory } from './entity_state' import { createSelectorsFactory } from './state_selectors' import { createSortedStateAdapter } from './sorted_state_adapter' import { createUnsortedStateAdapter } from './unsorted_state_adapter' +import type { WithRequiredProp } from '../tsHelpers' -export interface EntityAdapterOptions { - selectId?: IdSelector - sortComparer?: false | Comparer -} - -export function createEntityAdapter(options: { - selectId: IdSelector - sortComparer?: false | Comparer -}): EntityAdapter +export function createEntityAdapter( + options: WithRequiredProp, 'selectId'>, +): EntityAdapter -export function createEntityAdapter(options?: { - sortComparer?: false | Comparer -}): EntityAdapter +export function createEntityAdapter( + options?: Omit, 'selectId'>, +): EntityAdapter /** * @@ -31,12 +20,12 @@ export function createEntityAdapter(options?: { * @public */ export function createEntityAdapter( - options: { - selectId?: IdSelector - sortComparer?: false | Comparer - } = {}, + options: EntityAdapterOptions = {}, ): EntityAdapter { - const { selectId, sortComparer }: EntityDefinition = { + const { + selectId, + sortComparer, + }: Required> = { sortComparer: false, selectId: (instance: any) => instance.id, ...options, diff --git a/packages/toolkit/src/entities/models.ts b/packages/toolkit/src/entities/models.ts index 02cc01701e..76de9872fd 100644 --- a/packages/toolkit/src/entities/models.ts +++ b/packages/toolkit/src/entities/models.ts @@ -35,9 +35,9 @@ export interface EntityState { /** * @public */ -export interface EntityDefinition { - selectId: IdSelector - sortComparer: false | Comparer +export interface EntityAdapterOptions { + selectId?: IdSelector + sortComparer?: false | Comparer } export type PreventAny = CastAny< @@ -166,6 +166,9 @@ export interface EntitySelectors { selectById: (state: V, id: Id) => Compute> } +/** + * @public + */ export interface EntityStateFactory { getInitialState( state?: undefined, @@ -182,9 +185,8 @@ export interface EntityStateFactory { */ export interface EntityAdapter extends EntityStateAdapter, - EntityStateFactory { - selectId: IdSelector - sortComparer: false | Comparer + EntityStateFactory, + Required> { getSelectors( selectState?: undefined, options?: GetSelectorsOptions, From 52b560455124b3482528d7c9239f638abcbeee77 Mon Sep 17 00:00:00 2001 From: EskiMojo14 Date: Sun, 11 Feb 2024 17:32:36 +0000 Subject: [PATCH 3/4] add test --- .../src/entities/tests/entity_state.test.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/toolkit/src/entities/tests/entity_state.test.ts b/packages/toolkit/src/entities/tests/entity_state.test.ts index 65accf475c..999ee502b9 100644 --- a/packages/toolkit/src/entities/tests/entity_state.test.ts +++ b/packages/toolkit/src/entities/tests/entity_state.test.ts @@ -35,6 +35,27 @@ describe('Entity State', () => { }) }) + it('should let you provide initial entities', () => { + const book1: BookModel = { id: 'a', title: 'First' } + + const initialState = adapter.getInitialState(undefined, [book1]) + + expect(initialState).toEqual({ + ids: [book1.id], + entities: { [book1.id]: book1 }, + }) + + const additionalProperties = { isHydrated: true } + + const initialState2 = adapter.getInitialState(additionalProperties, [book1]) + + expect(initialState2).toEqual({ + ...additionalProperties, + ids: [book1.id], + entities: { [book1.id]: book1 }, + }) + }) + it('should allow methods to be passed as reducers', () => { const upsertBook = createAction('otherBooks/upsert') From cb6717d08051c06845840a6e7c8ba3a70ddd3454 Mon Sep 17 00:00:00 2001 From: EskiMojo14 Date: Sun, 11 Feb 2024 20:36:38 +0000 Subject: [PATCH 4/4] possibly shave some bytes --- packages/toolkit/src/entities/create_adapter.ts | 2 +- packages/toolkit/src/entities/entity_state.ts | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/toolkit/src/entities/create_adapter.ts b/packages/toolkit/src/entities/create_adapter.ts index 0dc936c704..de9ec83f19 100644 --- a/packages/toolkit/src/entities/create_adapter.ts +++ b/packages/toolkit/src/entities/create_adapter.ts @@ -34,7 +34,7 @@ export function createEntityAdapter( const stateAdapter = sortComparer ? createSortedStateAdapter(selectId, sortComparer) : createUnsortedStateAdapter(selectId) - const stateFactory = createInitialStateFactory({ stateAdapter }) + const stateFactory = createInitialStateFactory(stateAdapter) const selectorsFactory = createSelectorsFactory() return { diff --git a/packages/toolkit/src/entities/entity_state.ts b/packages/toolkit/src/entities/entity_state.ts index f235f8c7d2..9631aec6b5 100644 --- a/packages/toolkit/src/entities/entity_state.ts +++ b/packages/toolkit/src/entities/entity_state.ts @@ -15,11 +15,9 @@ export function getInitialEntityState(): EntityState< } } -export function createInitialStateFactory({ - stateAdapter, -}: { - stateAdapter: EntityStateAdapter -}): EntityStateFactory { +export function createInitialStateFactory( + stateAdapter: EntityStateAdapter, +): EntityStateFactory { function getInitialState( state?: undefined, entities?: readonly T[] | Record,