import type { Draft } from 'immer' import type { PayloadAction } from '../createAction' import type { CastAny, Id } from '../tsHelpers' import type { UncheckedIndexedAccess } from '../uncheckedindexed.js' import type { GetSelectorsOptions } from './state_selectors' /** * @public */ export type EntityId = number | string /** * @public */ export type Comparer = (a: T, b: T) => number /** * @public */ export type IdSelector = (model: T) => Id /** * @public */ export type Update = { id: Id; changes: Partial } /** * @public */ export interface EntityState { ids: Id[] entities: Record } /** * @public */ export interface EntityAdapterOptions { selectId?: IdSelector sortComparer?: false | Comparer } export type PreventAny = CastAny< S, EntityState > export type DraftableEntityState = | EntityState | Draft> /** * @public */ export interface EntityStateAdapter { addOne>( state: PreventAny, entity: T, ): S addOne>( state: PreventAny, action: PayloadAction, ): S addMany>( state: PreventAny, entities: readonly T[] | Record, ): S addMany>( state: PreventAny, entities: PayloadAction>, ): S setOne>( state: PreventAny, entity: T, ): S setOne>( state: PreventAny, action: PayloadAction, ): S setMany>( state: PreventAny, entities: readonly T[] | Record, ): S setMany>( state: PreventAny, entities: PayloadAction>, ): S setAll>( state: PreventAny, entities: readonly T[] | Record, ): S setAll>( state: PreventAny, entities: PayloadAction>, ): S removeOne>( state: PreventAny, key: Id, ): S removeOne>( state: PreventAny, key: PayloadAction, ): S removeMany>( state: PreventAny, keys: readonly Id[], ): S removeMany>( state: PreventAny, keys: PayloadAction, ): S removeAll>( state: PreventAny, ): S updateOne>( state: PreventAny, update: Update, ): S updateOne>( state: PreventAny, update: PayloadAction>, ): S updateMany>( state: PreventAny, updates: ReadonlyArray>, ): S updateMany>( state: PreventAny, updates: PayloadAction>>, ): S upsertOne>( state: PreventAny, entity: T, ): S upsertOne>( state: PreventAny, entity: PayloadAction, ): S upsertMany>( state: PreventAny, entities: readonly T[] | Record, ): S upsertMany>( state: PreventAny, entities: PayloadAction>, ): S } /** * @public */ export interface EntitySelectors { selectIds: (state: V) => IdType[] selectEntities: (state: V) => Record selectAll: (state: V) => T[] selectTotal: (state: V) => number selectById: (state: V, id: IdType) => Id> } /** * @public */ 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, EntityStateFactory, Required> { getSelectors( selectState?: undefined, options?: GetSelectorsOptions, ): EntitySelectors, Id> getSelectors( selectState: (state: V) => EntityState, options?: GetSelectorsOptions, ): EntitySelectors }