UNPKG

@ngrx/entity

Version:

Common utilities for entity reducers

143 lines (139 loc) 5.67 kB
import { MemoizedSelector } from '@ngrx/store'; type Comparer<T> = (a: T, b: T) => number; type IdSelectorStr<T> = (model: T) => string; type IdSelectorNum<T> = (model: T) => number; type IdSelector<T> = IdSelectorStr<T> | IdSelectorNum<T>; interface DictionaryNum<T> { [id: number]: T | undefined; } declare abstract class Dictionary<T> implements DictionaryNum<T> { [id: string]: T | undefined; } interface UpdateStr<T> { id: string; changes: Partial<T>; } interface UpdateNum<T> { id: number; changes: Partial<T>; } type Update<T> = UpdateStr<T> | UpdateNum<T>; type Predicate<T> = (entity: T) => boolean; type EntityMap<T> = (entity: T) => T; interface EntityMapOneNum<T> { id: number; map: EntityMap<T>; } interface EntityMapOneStr<T> { id: string; map: EntityMap<T>; } type EntityMapOne<T> = EntityMapOneNum<T> | EntityMapOneStr<T>; interface EntityState<T> { ids: string[] | number[]; entities: Dictionary<T>; } interface EntityStateAdapter<T> { addOne<S extends EntityState<T>>(entity: T, state: S): S; addMany<S extends EntityState<T>>(entities: T[], state: S): S; setAll<S extends EntityState<T>>(entities: T[], state: S): S; setOne<S extends EntityState<T>>(entity: T, state: S): S; setMany<S extends EntityState<T>>(entities: T[], state: S): S; removeOne<S extends EntityState<T>>(key: string, state: S): S; removeOne<S extends EntityState<T>>(key: number, state: S): S; removeMany<S extends EntityState<T>>(keys: string[], state: S): S; removeMany<S extends EntityState<T>>(keys: number[], state: S): S; removeMany<S extends EntityState<T>>(predicate: Predicate<T>, state: S): S; removeAll<S extends EntityState<T>>(state: S): S; updateOne<S extends EntityState<T>>(update: Update<T>, state: S): S; updateMany<S extends EntityState<T>>(updates: Update<T>[], state: S): S; upsertOne<S extends EntityState<T>>(entity: T, state: S): S; upsertMany<S extends EntityState<T>>(entities: T[], state: S): S; mapOne<S extends EntityState<T>>(map: EntityMapOne<T>, state: S): S; map<S extends EntityState<T>>(map: EntityMap<T>, state: S): S; } type EntitySelectors<T, V> = { selectIds: (state: V) => string[] | number[]; selectEntities: (state: V) => Dictionary<T>; selectAll: (state: V) => T[]; selectTotal: (state: V) => number; }; type MemoizedEntitySelectors<T, V> = { selectIds: MemoizedSelector<V, string[] | number[], (entityState: EntityState<T>) => string[] | number[]>; selectEntities: MemoizedSelector<V, Dictionary<T>, (entityState: EntityState<T>) => Dictionary<T>>; selectAll: MemoizedSelector<V, T[], (entityState: EntityState<T>) => T[]>; selectTotal: MemoizedSelector<V, number, (entityState: EntityState<T>) => number>; }; interface EntityAdapter<T, IdType = string | number> extends EntityStateAdapter<T> { selectId: IdType extends string ? IdSelectorStr<T> : IdType extends number ? IdSelectorNum<T> : unknown; sortComparer: false | Comparer<T>; getInitialState(): EntityState<T>; getInitialState<S extends EntityState<T>>(state: Omit<S, keyof EntityState<T>>): S; getSelectors(): EntitySelectors<T, EntityState<T>>; getSelectors<V>(selectState: (state: V) => EntityState<T>): MemoizedEntitySelectors<T, V>; } /** * Creates an entity adapter with methods for managing collections of entities in state. * * @description * The entity adapter provides a set of predefined reducers and selectors for managing * normalized entity collections. It includes methods for adding, updating, removing, * and selecting entities from state. * * @template T - The entity type to be managed by the adapter * * @param options - Configuration options for the adapter * @param options.selectId - A function that selects the unique identifier from an entity. * Defaults to `(entity) => entity.id` if not provided. * @param options.sortComparer - A comparer function for sorting entities in state. * Set to `false` (default) to maintain insertion order, or provide a comparer function * to keep entities sorted. * * @returns An entity adapter containing methods for managing and selecting entity collections in state. * * @example * ```typescript * // Entity with default 'id' property * interface User { * id: number; * name: string; * } * const userAdapter = createEntityAdapter<User>(); * * // Entity with custom id field * interface Book { * isbn: string; * title: string; * } * const bookAdapter = createEntityAdapter<Book>({ * selectId: (book) => book.isbn, * }); * * // Entity with sorting * const sortedBookAdapter = createEntityAdapter<Book>({ * sortComparer: (a, b) => a.title.localeCompare(b.title), * }); * ``` */ declare function createEntityAdapter<T extends { id: string | number; }>(options?: { sortComparer?: false | Comparer<T>; }): EntityAdapter<T, T extends { id: infer U; } ? U : never>; declare function createEntityAdapter<T>(options: { selectId: IdSelectorStr<T>; sortComparer?: false | Comparer<T>; }): EntityAdapter<T, string>; declare function createEntityAdapter<T>(options: { selectId: IdSelectorNum<T>; sortComparer?: false | Comparer<T>; }): EntityAdapter<T, number>; declare function createEntityAdapter<T>(options: { selectId: IdSelector<T>; sortComparer?: false | Comparer<T>; }): EntityAdapter<T>; declare function createEntityAdapter<T>(): EntityAdapter<T>; export { Dictionary, createEntityAdapter }; export type { Comparer, DictionaryNum, EntityAdapter, EntityMap, EntityMapOne, EntitySelectors, EntityState, IdSelector, MemoizedEntitySelectors, Predicate, Update };