/
utils.ts
62 lines (53 loc) · 1.55 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { current } from 'immer'
import type {
IdSelector,
Update,
EntityId,
DraftableEntityState,
} from './models'
export function selectIdValue<T, Id extends EntityId>(
entity: T,
selectId: IdSelector<T, Id>,
) {
const key = selectId(entity)
if (process.env.NODE_ENV !== 'production' && key === undefined) {
console.warn(
'The entity passed to the `selectId` implementation returned undefined.',
'You should probably provide your own `selectId` implementation.',
'The entity that was passed:',
entity,
'The `selectId` implementation:',
selectId.toString(),
)
}
return key
}
export function ensureEntitiesArray<T, Id extends EntityId>(
entities: readonly T[] | Record<Id, T>,
): readonly T[] {
if (!Array.isArray(entities)) {
entities = Object.values(entities)
}
return entities
}
export function splitAddedUpdatedEntities<T, Id extends EntityId>(
newEntities: readonly T[] | Record<Id, T>,
selectId: IdSelector<T, Id>,
state: DraftableEntityState<T, Id>,
): [T[], Update<T, Id>[], Id[]] {
newEntities = ensureEntitiesArray(newEntities)
const existingIdsArray = current(state.ids) as Id[]
const existingIds = new Set<Id>(existingIdsArray)
const added: T[] = []
const updated: Update<T, Id>[] = []
for (const entity of newEntities) {
const id = selectIdValue(entity, selectId)
if (existingIds.has(id)) {
// if (id in state.entities) {
updated.push({ id, changes: entity })
} else {
added.push(entity)
}
}
return [added, updated, existingIdsArray]
}