UNPKG

15.9 kBJavaScriptView Raw
1import { createSelector } from '@ngrx/store';
2import { isDevMode } from '@angular/core';
3
4function getInitialEntityState() {
5 return {
6 ids: [],
7 entities: {},
8 };
9}
10function createInitialStateFactory() {
11 function getInitialState(additionalState = {}) {
12 return Object.assign(getInitialEntityState(), additionalState);
13 }
14 return { getInitialState };
15}
16
17function createSelectorsFactory() {
18 function getSelectors(selectState) {
19 const selectIds = (state) => state.ids;
20 const selectEntities = (state) => state.entities;
21 const selectAll = createSelector(selectIds, selectEntities, (ids, entities) => ids.map((id) => entities[id]));
22 const selectTotal = createSelector(selectIds, (ids) => ids.length);
23 if (!selectState) {
24 return {
25 selectIds,
26 selectEntities,
27 selectAll,
28 selectTotal,
29 };
30 }
31 return {
32 selectIds: createSelector(selectState, selectIds),
33 selectEntities: createSelector(selectState, selectEntities),
34 selectAll: createSelector(selectState, selectAll),
35 selectTotal: createSelector(selectState, selectTotal),
36 };
37 }
38 return { getSelectors };
39}
40
41var DidMutate;
42(function (DidMutate) {
43 DidMutate[DidMutate["EntitiesOnly"] = 0] = "EntitiesOnly";
44 DidMutate[DidMutate["Both"] = 1] = "Both";
45 DidMutate[DidMutate["None"] = 2] = "None";
46})(DidMutate || (DidMutate = {}));
47function createStateOperator(mutator) {
48 return function operation(arg, state) {
49 const clonedEntityState = {
50 ids: [...state.ids],
51 entities: { ...state.entities },
52 };
53 const didMutate = mutator(arg, clonedEntityState);
54 if (didMutate === DidMutate.Both) {
55 return Object.assign({}, state, clonedEntityState);
56 }
57 if (didMutate === DidMutate.EntitiesOnly) {
58 return {
59 ...state,
60 entities: clonedEntityState.entities,
61 };
62 }
63 return state;
64 };
65}
66
67function selectIdValue(entity, selectId) {
68 const key = selectId(entity);
69 if (isDevMode() && key === undefined) {
70 console.warn('@ngrx/entity: 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());
71 }
72 return key;
73}
74
75function createUnsortedStateAdapter(selectId) {
76 function addOneMutably(entity, state) {
77 const key = selectIdValue(entity, selectId);
78 if (key in state.entities) {
79 return DidMutate.None;
80 }
81 state.ids.push(key);
82 state.entities[key] = entity;
83 return DidMutate.Both;
84 }
85 function addManyMutably(entities, state) {
86 let didMutate = false;
87 for (const entity of entities) {
88 didMutate = addOneMutably(entity, state) !== DidMutate.None || didMutate;
89 }
90 return didMutate ? DidMutate.Both : DidMutate.None;
91 }
92 function setAllMutably(entities, state) {
93 state.ids = [];
94 state.entities = {};
95 addManyMutably(entities, state);
96 return DidMutate.Both;
97 }
98 function setOneMutably(entity, state) {
99 const key = selectIdValue(entity, selectId);
100 if (key in state.entities) {
101 state.entities[key] = entity;
102 return DidMutate.EntitiesOnly;
103 }
104 state.ids.push(key);
105 state.entities[key] = entity;
106 return DidMutate.Both;
107 }
108 function setManyMutably(entities, state) {
109 const didMutateSetOne = entities.map((entity) => setOneMutably(entity, state));
110 switch (true) {
111 case didMutateSetOne.some((didMutate) => didMutate === DidMutate.Both):
112 return DidMutate.Both;
113 case didMutateSetOne.some((didMutate) => didMutate === DidMutate.EntitiesOnly):
114 return DidMutate.EntitiesOnly;
115 default:
116 return DidMutate.None;
117 }
118 }
119 function removeOneMutably(key, state) {
120 return removeManyMutably([key], state);
121 }
122 function removeManyMutably(keysOrPredicate, state) {
123 const keys = keysOrPredicate instanceof Array
124 ? keysOrPredicate
125 : state.ids.filter((key) => keysOrPredicate(state.entities[key]));
126 const didMutate = keys
127 .filter((key) => key in state.entities)
128 .map((key) => delete state.entities[key]).length > 0;
129 if (didMutate) {
130 state.ids = state.ids.filter((id) => id in state.entities);
131 }
132 return didMutate ? DidMutate.Both : DidMutate.None;
133 }
134 function removeAll(state) {
135 return Object.assign({}, state, {
136 ids: [],
137 entities: {},
138 });
139 }
140 function takeNewKey(keys, update, state) {
141 const original = state.entities[update.id];
142 const updated = Object.assign({}, original, update.changes);
143 const newKey = selectIdValue(updated, selectId);
144 const hasNewKey = newKey !== update.id;
145 if (hasNewKey) {
146 keys[update.id] = newKey;
147 delete state.entities[update.id];
148 }
149 state.entities[newKey] = updated;
150 return hasNewKey;
151 }
152 function updateOneMutably(update, state) {
153 return updateManyMutably([update], state);
154 }
155 function updateManyMutably(updates, state) {
156 const newKeys = {};
157 updates = updates.filter((update) => update.id in state.entities);
158 const didMutateEntities = updates.length > 0;
159 if (didMutateEntities) {
160 const didMutateIds = updates.filter((update) => takeNewKey(newKeys, update, state)).length >
161 0;
162 if (didMutateIds) {
163 state.ids = state.ids.map((id) => newKeys[id] || id);
164 return DidMutate.Both;
165 }
166 else {
167 return DidMutate.EntitiesOnly;
168 }
169 }
170 return DidMutate.None;
171 }
172 function mapMutably(map, state) {
173 const changes = state.ids.reduce((changes, id) => {
174 const change = map(state.entities[id]);
175 if (change !== state.entities[id]) {
176 changes.push({ id, changes: change });
177 }
178 return changes;
179 }, []);
180 const updates = changes.filter(({ id }) => id in state.entities);
181 return updateManyMutably(updates, state);
182 }
183 function mapOneMutably({ map, id }, state) {
184 const entity = state.entities[id];
185 if (!entity) {
186 return DidMutate.None;
187 }
188 const updatedEntity = map(entity);
189 return updateOneMutably({
190 id: id,
191 changes: updatedEntity,
192 }, state);
193 }
194 function upsertOneMutably(entity, state) {
195 return upsertManyMutably([entity], state);
196 }
197 function upsertManyMutably(entities, state) {
198 const added = [];
199 const updated = [];
200 for (const entity of entities) {
201 const id = selectIdValue(entity, selectId);
202 if (id in state.entities) {
203 updated.push({ id, changes: entity });
204 }
205 else {
206 added.push(entity);
207 }
208 }
209 const didMutateByUpdated = updateManyMutably(updated, state);
210 const didMutateByAdded = addManyMutably(added, state);
211 switch (true) {
212 case didMutateByAdded === DidMutate.None &&
213 didMutateByUpdated === DidMutate.None:
214 return DidMutate.None;
215 case didMutateByAdded === DidMutate.Both ||
216 didMutateByUpdated === DidMutate.Both:
217 return DidMutate.Both;
218 default:
219 return DidMutate.EntitiesOnly;
220 }
221 }
222 return {
223 removeAll,
224 addOne: createStateOperator(addOneMutably),
225 addMany: createStateOperator(addManyMutably),
226 setAll: createStateOperator(setAllMutably),
227 setOne: createStateOperator(setOneMutably),
228 setMany: createStateOperator(setManyMutably),
229 updateOne: createStateOperator(updateOneMutably),
230 updateMany: createStateOperator(updateManyMutably),
231 upsertOne: createStateOperator(upsertOneMutably),
232 upsertMany: createStateOperator(upsertManyMutably),
233 removeOne: createStateOperator(removeOneMutably),
234 removeMany: createStateOperator(removeManyMutably),
235 map: createStateOperator(mapMutably),
236 mapOne: createStateOperator(mapOneMutably),
237 };
238}
239
240function createSortedStateAdapter(selectId, sort) {
241 const { removeOne, removeMany, removeAll } = createUnsortedStateAdapter(selectId);
242 function addOneMutably(entity, state) {
243 return addManyMutably([entity], state);
244 }
245 function addManyMutably(newModels, state) {
246 const models = newModels.filter((model) => !(selectIdValue(model, selectId) in state.entities));
247 if (models.length === 0) {
248 return DidMutate.None;
249 }
250 else {
251 merge(models, state);
252 return DidMutate.Both;
253 }
254 }
255 function setAllMutably(models, state) {
256 state.entities = {};
257 state.ids = [];
258 addManyMutably(models, state);
259 return DidMutate.Both;
260 }
261 function setOneMutably(entity, state) {
262 const id = selectIdValue(entity, selectId);
263 if (id in state.entities) {
264 state.ids = state.ids.filter((val) => val !== id);
265 merge([entity], state);
266 return DidMutate.Both;
267 }
268 else {
269 return addOneMutably(entity, state);
270 }
271 }
272 function setManyMutably(entities, state) {
273 const didMutateSetOne = entities.map((entity) => setOneMutably(entity, state));
274 switch (true) {
275 case didMutateSetOne.some((didMutate) => didMutate === DidMutate.Both):
276 return DidMutate.Both;
277 case didMutateSetOne.some((didMutate) => didMutate === DidMutate.EntitiesOnly):
278 return DidMutate.EntitiesOnly;
279 default:
280 return DidMutate.None;
281 }
282 }
283 function updateOneMutably(update, state) {
284 return updateManyMutably([update], state);
285 }
286 function takeUpdatedModel(models, update, state) {
287 if (!(update.id in state.entities)) {
288 return false;
289 }
290 const original = state.entities[update.id];
291 const updated = Object.assign({}, original, update.changes);
292 const newKey = selectIdValue(updated, selectId);
293 delete state.entities[update.id];
294 models.push(updated);
295 return newKey !== update.id;
296 }
297 function updateManyMutably(updates, state) {
298 const models = [];
299 const didMutateIds = updates.filter((update) => takeUpdatedModel(models, update, state))
300 .length > 0;
301 if (models.length === 0) {
302 return DidMutate.None;
303 }
304 else {
305 const originalIds = state.ids;
306 const updatedIndexes = [];
307 state.ids = state.ids.filter((id, index) => {
308 if (id in state.entities) {
309 return true;
310 }
311 else {
312 updatedIndexes.push(index);
313 return false;
314 }
315 });
316 merge(models, state);
317 if (!didMutateIds &&
318 updatedIndexes.every((i) => state.ids[i] === originalIds[i])) {
319 return DidMutate.EntitiesOnly;
320 }
321 else {
322 return DidMutate.Both;
323 }
324 }
325 }
326 function mapMutably(updatesOrMap, state) {
327 const updates = state.ids.reduce((changes, id) => {
328 const change = updatesOrMap(state.entities[id]);
329 if (change !== state.entities[id]) {
330 changes.push({ id, changes: change });
331 }
332 return changes;
333 }, []);
334 return updateManyMutably(updates, state);
335 }
336 function mapOneMutably({ map, id }, state) {
337 const entity = state.entities[id];
338 if (!entity) {
339 return DidMutate.None;
340 }
341 const updatedEntity = map(entity);
342 return updateOneMutably({
343 id: id,
344 changes: updatedEntity,
345 }, state);
346 }
347 function upsertOneMutably(entity, state) {
348 return upsertManyMutably([entity], state);
349 }
350 function upsertManyMutably(entities, state) {
351 const added = [];
352 const updated = [];
353 for (const entity of entities) {
354 const id = selectIdValue(entity, selectId);
355 if (id in state.entities) {
356 updated.push({ id, changes: entity });
357 }
358 else {
359 added.push(entity);
360 }
361 }
362 const didMutateByUpdated = updateManyMutably(updated, state);
363 const didMutateByAdded = addManyMutably(added, state);
364 switch (true) {
365 case didMutateByAdded === DidMutate.None &&
366 didMutateByUpdated === DidMutate.None:
367 return DidMutate.None;
368 case didMutateByAdded === DidMutate.Both ||
369 didMutateByUpdated === DidMutate.Both:
370 return DidMutate.Both;
371 default:
372 return DidMutate.EntitiesOnly;
373 }
374 }
375 function merge(models, state) {
376 models.sort(sort);
377 const ids = [];
378 let i = 0;
379 let j = 0;
380 while (i < models.length && j < state.ids.length) {
381 const model = models[i];
382 const modelId = selectIdValue(model, selectId);
383 const entityId = state.ids[j];
384 const entity = state.entities[entityId];
385 if (sort(model, entity) <= 0) {
386 ids.push(modelId);
387 i++;
388 }
389 else {
390 ids.push(entityId);
391 j++;
392 }
393 }
394 if (i < models.length) {
395 state.ids = ids.concat(models.slice(i).map(selectId));
396 }
397 else {
398 state.ids = ids.concat(state.ids.slice(j));
399 }
400 models.forEach((model, i) => {
401 state.entities[selectId(model)] = model;
402 });
403 }
404 return {
405 removeOne,
406 removeMany,
407 removeAll,
408 addOne: createStateOperator(addOneMutably),
409 updateOne: createStateOperator(updateOneMutably),
410 upsertOne: createStateOperator(upsertOneMutably),
411 setAll: createStateOperator(setAllMutably),
412 setOne: createStateOperator(setOneMutably),
413 setMany: createStateOperator(setManyMutably),
414 addMany: createStateOperator(addManyMutably),
415 updateMany: createStateOperator(updateManyMutably),
416 upsertMany: createStateOperator(upsertManyMutably),
417 map: createStateOperator(mapMutably),
418 mapOne: createStateOperator(mapOneMutably),
419 };
420}
421
422function createEntityAdapter(options = {}) {
423 const { selectId, sortComparer } = {
424 selectId: options.selectId ?? ((entity) => entity.id),
425 sortComparer: options.sortComparer ?? false,
426 };
427 const stateFactory = createInitialStateFactory();
428 const selectorsFactory = createSelectorsFactory();
429 const stateAdapter = sortComparer
430 ? createSortedStateAdapter(selectId, sortComparer)
431 : createUnsortedStateAdapter(selectId);
432 return {
433 selectId,
434 sortComparer,
435 ...stateFactory,
436 ...selectorsFactory,
437 ...stateAdapter,
438 };
439}
440
441class Dictionary {
442}
443
444/**
445 * DO NOT EDIT
446 *
447 * This file is automatically generated at build
448 */
449
450/**
451 * Generated bundle index. Do not edit.
452 */
453
454export { Dictionary, createEntityAdapter };
455//# sourceMappingURL=ngrx-entity.mjs.map