UNPKG

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