1 | import type { EntityState, IdSelector, Update, EntityId } from './models'
|
2 |
|
3 | export function selectIdValue<T>(entity: T, selectId: IdSelector<T>) {
|
4 | const key = selectId(entity)
|
5 |
|
6 | if (process.env.NODE_ENV !== 'production' && key === undefined) {
|
7 | console.warn(
|
8 | 'The entity passed to the `selectId` implementation returned undefined.',
|
9 | 'You should probably provide your own `selectId` implementation.',
|
10 | 'The entity that was passed:',
|
11 | entity,
|
12 | 'The `selectId` implementation:',
|
13 | selectId.toString()
|
14 | )
|
15 | }
|
16 |
|
17 | return key
|
18 | }
|
19 |
|
20 | export function ensureEntitiesArray<T>(
|
21 | entities: readonly T[] | Record<EntityId, T>
|
22 | ): readonly T[] {
|
23 | if (!Array.isArray(entities)) {
|
24 | entities = Object.values(entities)
|
25 | }
|
26 |
|
27 | return entities
|
28 | }
|
29 |
|
30 | export function splitAddedUpdatedEntities<T>(
|
31 | newEntities: readonly T[] | Record<EntityId, T>,
|
32 | selectId: IdSelector<T>,
|
33 | state: EntityState<T>
|
34 | ): [T[], Update<T>[]] {
|
35 | newEntities = ensureEntitiesArray(newEntities)
|
36 |
|
37 | const added: T[] = []
|
38 | const updated: Update<T>[] = []
|
39 |
|
40 | for (const entity of newEntities) {
|
41 | const id = selectIdValue(entity, selectId)
|
42 | if (id in state.entities) {
|
43 | updated.push({ id, changes: entity })
|
44 | } else {
|
45 | added.push(entity)
|
46 | }
|
47 | }
|
48 | return [added, updated]
|
49 | }
|