1 | import type { PayloadAction } from '../createAction'
|
2 | import type { IsAny } from '../tsHelpers'
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | export type EntityId = number | string
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | export type Comparer<T> = (a: T, b: T) => number
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | export type IdSelector<T> = (model: T) => EntityId
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | export interface DictionaryNum<T> {
|
23 | [id: number]: T | undefined
|
24 | }
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | export interface Dictionary<T> extends DictionaryNum<T> {
|
30 | [id: string]: T | undefined
|
31 | }
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | export type Update<T> = { id: EntityId; changes: Partial<T> }
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | export interface EntityState<T> {
|
42 | ids: EntityId[]
|
43 | entities: Dictionary<T>
|
44 | }
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | export interface EntityDefinition<T> {
|
50 | selectId: IdSelector<T>
|
51 | sortComparer: false | Comparer<T>
|
52 | }
|
53 |
|
54 | export type PreventAny<S, T> = IsAny<S, EntityState<T>, S>
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | export interface EntityStateAdapter<T> {
|
60 | addOne<S extends EntityState<T>>(state: PreventAny<S, T>, entity: T): S
|
61 | addOne<S extends EntityState<T>>(
|
62 | state: PreventAny<S, T>,
|
63 | action: PayloadAction<T>
|
64 | ): S
|
65 |
|
66 | addMany<S extends EntityState<T>>(
|
67 | state: PreventAny<S, T>,
|
68 | entities: readonly T[] | Record<EntityId, T>
|
69 | ): S
|
70 | addMany<S extends EntityState<T>>(
|
71 | state: PreventAny<S, T>,
|
72 | entities: PayloadAction<readonly T[] | Record<EntityId, T>>
|
73 | ): S
|
74 |
|
75 | setOne<S extends EntityState<T>>(state: PreventAny<S, T>, entity: T): S
|
76 | setOne<S extends EntityState<T>>(
|
77 | state: PreventAny<S, T>,
|
78 | action: PayloadAction<T>
|
79 | ): S
|
80 | setMany<S extends EntityState<T>>(
|
81 | state: PreventAny<S, T>,
|
82 | entities: readonly T[] | Record<EntityId, T>
|
83 | ): S
|
84 | setMany<S extends EntityState<T>>(
|
85 | state: PreventAny<S, T>,
|
86 | entities: PayloadAction<readonly T[] | Record<EntityId, T>>
|
87 | ): S
|
88 | setAll<S extends EntityState<T>>(
|
89 | state: PreventAny<S, T>,
|
90 | entities: readonly T[] | Record<EntityId, T>
|
91 | ): S
|
92 | setAll<S extends EntityState<T>>(
|
93 | state: PreventAny<S, T>,
|
94 | entities: PayloadAction<readonly T[] | Record<EntityId, T>>
|
95 | ): S
|
96 |
|
97 | removeOne<S extends EntityState<T>>(state: PreventAny<S, T>, key: EntityId): S
|
98 | removeOne<S extends EntityState<T>>(
|
99 | state: PreventAny<S, T>,
|
100 | key: PayloadAction<EntityId>
|
101 | ): S
|
102 |
|
103 | removeMany<S extends EntityState<T>>(
|
104 | state: PreventAny<S, T>,
|
105 | keys: readonly EntityId[]
|
106 | ): S
|
107 | removeMany<S extends EntityState<T>>(
|
108 | state: PreventAny<S, T>,
|
109 | keys: PayloadAction<readonly EntityId[]>
|
110 | ): S
|
111 |
|
112 | removeAll<S extends EntityState<T>>(state: PreventAny<S, T>): S
|
113 |
|
114 | updateOne<S extends EntityState<T>>(
|
115 | state: PreventAny<S, T>,
|
116 | update: Update<T>
|
117 | ): S
|
118 | updateOne<S extends EntityState<T>>(
|
119 | state: PreventAny<S, T>,
|
120 | update: PayloadAction<Update<T>>
|
121 | ): S
|
122 |
|
123 | updateMany<S extends EntityState<T>>(
|
124 | state: PreventAny<S, T>,
|
125 | updates: ReadonlyArray<Update<T>>
|
126 | ): S
|
127 | updateMany<S extends EntityState<T>>(
|
128 | state: PreventAny<S, T>,
|
129 | updates: PayloadAction<ReadonlyArray<Update<T>>>
|
130 | ): S
|
131 |
|
132 | upsertOne<S extends EntityState<T>>(state: PreventAny<S, T>, entity: T): S
|
133 | upsertOne<S extends EntityState<T>>(
|
134 | state: PreventAny<S, T>,
|
135 | entity: PayloadAction<T>
|
136 | ): S
|
137 |
|
138 | upsertMany<S extends EntityState<T>>(
|
139 | state: PreventAny<S, T>,
|
140 | entities: readonly T[] | Record<EntityId, T>
|
141 | ): S
|
142 | upsertMany<S extends EntityState<T>>(
|
143 | state: PreventAny<S, T>,
|
144 | entities: PayloadAction<readonly T[] | Record<EntityId, T>>
|
145 | ): S
|
146 | }
|
147 |
|
148 |
|
149 |
|
150 |
|
151 | export interface EntitySelectors<T, V> {
|
152 | selectIds: (state: V) => EntityId[]
|
153 | selectEntities: (state: V) => Dictionary<T>
|
154 | selectAll: (state: V) => T[]
|
155 | selectTotal: (state: V) => number
|
156 | selectById: (state: V, id: EntityId) => T | undefined
|
157 | }
|
158 |
|
159 |
|
160 |
|
161 |
|
162 | export interface EntityAdapter<T> extends EntityStateAdapter<T> {
|
163 | selectId: IdSelector<T>
|
164 | sortComparer: false | Comparer<T>
|
165 | getInitialState(): EntityState<T>
|
166 | getInitialState<S extends object>(state: S): EntityState<T> & S
|
167 | getSelectors(): EntitySelectors<T, EntityState<T>>
|
168 | getSelectors<V>(
|
169 | selectState: (state: V) => EntityState<T>
|
170 | ): EntitySelectors<T, V>
|
171 | }
|