@ngxs-labs/entity-state
Version:
<p align="center"> <img src="https://raw.githubusercontent.com/ngxs-labs/emitter/master/docs/assets/logo.png"> </p>
881 lines (859 loc) • 31.4 kB
JavaScript
import { createSelector, ofAction, ofActionDispatched, ofActionSuccessful, ofActionErrored, ofActionCompleted } from '@ngxs/store';
import { patch, compose } from '@ngxs/store/operators';
class EntityStateError extends Error {
constructor(message) {
super(message);
}
}
class NoActiveEntityError extends EntityStateError {
constructor(additionalInformation = '') {
super(('No active entity to affect. ' + additionalInformation).trim());
}
}
class NoSuchEntityError extends EntityStateError {
constructor(id) {
super(`No entity for ID ${id}`);
}
}
class InvalidIdError extends EntityStateError {
constructor(id) {
super(`Invalid ID: ${id}`);
}
}
class InvalidIdOfError extends EntityStateError {
constructor() {
super(`idOf returned undefined`);
}
}
class UpdateFailedError extends EntityStateError {
constructor(cause) {
super(`Updating entity failed.\n\tCause: ${cause}`);
}
}
class UnableToGenerateIdError extends EntityStateError {
constructor(cause) {
super(`Unable to generate an ID.\n\tCause: ${cause}`);
}
}
class InvalidEntitySelectorError extends EntityStateError {
constructor(invalidSelector) {
super(`Cannot use ${invalidSelector} as EntitySelector`);
}
}
const NGXS_META_KEY = 'NGXS_META';
/**
* This function generates a new object for the ngxs Action with the given fn name
* @param fn The name of the Action to simulate, e.g. "Remove" or "Update"
* @param store The class of the targeted entity state, e.g. ZooState
* @param payload The payload for the created action object
*/
function generateActionObject(fn, store, payload) {
const name = store[NGXS_META_KEY].path;
const ReflectedAction = function (data) {
this.payload = data;
};
const obj = new ReflectedAction(payload);
Reflect.getPrototypeOf(obj).constructor['type'] = `[${name}] ${fn}`;
return obj;
}
/**
* Utility function that returns the active entity of the given state
* @param state the state of an entity state
*/
function getActive(state) {
return state.entities[state.active];
}
/**
* Returns the active entity. If none is present an error will be thrown.
* @param state The state to act on
*/
function mustGetActive(state) {
const active = getActive(state);
if (active === undefined) {
throw new NoActiveEntityError();
}
return { id: state.active, active };
}
/**
* Undefined-safe function to access the property given by path parameter
* @param object The object to read from
* @param path The path to the property
*/
function elvis(object, path) {
return path ? path.split('.').reduce((value, key) => value && value[key], object) : object;
}
/**
* Returns input as an array if it isn't one already
* @param input The input to make an array if necessary
*/
function asArray(input) {
return Array.isArray(input) ? input : [input];
}
/**
* Limits a number to the given boundaries
* @param value The input value
* @param min The minimum value
* @param max The maximum value
*/
function clamp(value, min, max) {
return Math.min(max, Math.max(min, value));
}
/**
* Uses the clamp function is wrap is false.
* Else it wrap to the max or min value respectively.
* @param wrap Flag to indicate if value should be wrapped
* @param value The input value
* @param min The minimum value
* @param max The maximum value
*/
function wrapOrClamp(wrap, value, min, max) {
if (!wrap) {
return clamp(value, min, max);
}
else if (value < min) {
return max;
}
else if (value > max) {
return min;
}
else {
return value;
}
}
/**
* Enum that contains all existing Actions for the Entity State adapter.
*/
var EntityActionType;
(function (EntityActionType) {
EntityActionType["Add"] = "add";
EntityActionType["CreateOrReplace"] = "createOrReplace";
EntityActionType["Update"] = "update";
EntityActionType["UpdateAll"] = "updateAll";
EntityActionType["UpdateActive"] = "updateActive";
EntityActionType["Remove"] = "remove";
EntityActionType["RemoveAll"] = "removeAll";
EntityActionType["RemoveActive"] = "removeActive";
EntityActionType["SetLoading"] = "setLoading";
EntityActionType["SetError"] = "setError";
EntityActionType["SetActive"] = "setActive";
EntityActionType["ClearActive"] = "clearActive";
EntityActionType["Reset"] = "reset";
EntityActionType["GoToPage"] = "goToPage";
EntityActionType["SetPageSize"] = "setPageSize";
})(EntityActionType || (EntityActionType = {}));
class Add {
/**
* Generates an action that will add the given entities to the state.
* The entities given by the payload will be added.
* For certain ID strategies this might fail, if it provides an existing ID.
* In all other cases it will overwrite the ID value in the entity with the calculated ID.
* @param target The targeted state class
* @param payload An entity or an array of entities to be added
* @see CreateOrReplace#constructor
*/
constructor(target, payload) {
return generateActionObject(EntityActionType.Add, target, payload);
}
}
class CreateOrReplace {
/**
* Generates an action that will add the given entities to the state.
* If an entity with the ID already exists, it will be overridden.
* In all cases it will overwrite the ID value in the entity with the calculated ID.
* @param target The targeted state class
* @param payload An entity or an array of entities to be added
* @see Add#constructor
*/
constructor(target, payload) {
return generateActionObject(EntityActionType.CreateOrReplace, target, payload);
}
}
class Remove {
/**
* Generates an action that will remove the given entities from the state.
* @param target The targeted state class
* @param payload An EntitySelector payload
* @see EntitySelector
* @see RemoveAll
*/
constructor(target, payload) {
return generateActionObject(EntityActionType.Remove, target, payload);
}
}
class RemoveAll {
/**
* Generates an action that will remove all entities from the state.
* @param target The targeted state class
*/
constructor(target) {
return generateActionObject(EntityActionType.RemoveAll, target);
}
}
class Update {
/**
* Generates an action that will update all entities, specified by the given selector.
* @param target The targeted state class
* @param selector An EntitySelector that determines the entities to update
* @param data An Updater that will be applied to the selected entities
* @see EntitySelector
* @see Updater
*/
constructor(target, selector, data) {
return generateActionObject(EntityActionType.Update, target, {
selector,
data
});
}
}
class UpdateAll {
/**
* Generates an action that will update all entities.
* If no entity is active a runtime error will be thrown.
* @param target The targeted state class
* @param data An Updater that will be applied to all entities
* @see EntitySelector
* @see Updater
*/
constructor(target, data) {
return generateActionObject(EntityActionType.UpdateAll, target, {
data
});
}
}
class SetLoading {
/**
* Generates an action that will set the loading state for the given state.
* @param target The targeted state class
* @param loading The loading state
*/
constructor(target, loading) {
return generateActionObject(EntityActionType.SetLoading, target, loading);
}
}
class SetActive {
/**
* Generates an action that sets an ID that identifies the active entity
* @param target The targeted state class
* @param id The ID that identifies the active entity
*/
constructor(target, id) {
return generateActionObject(EntityActionType.SetActive, target, id);
}
}
class ClearActive {
/**
* Generates an action that clears the active entity in the given state
* @param target The targeted state class
*/
constructor(target) {
return generateActionObject(EntityActionType.ClearActive, target);
}
}
class RemoveActive {
/**
* Generates an action that removes the active entity from the state and clears the active ID.
* @param target The targeted state class
*/
constructor(target) {
return generateActionObject(EntityActionType.RemoveActive, target);
}
}
class UpdateActive {
/**
* Generates an action that will update the current active entity.
* If no entity is active a runtime error will be thrown.
* @param target The targeted state class
* @param payload An Updater payload
* @see Updater
*/
constructor(target, payload) {
return generateActionObject(EntityActionType.UpdateActive, target, payload);
}
}
class SetError {
/**
* Generates an action that will set the error state for the given state.
* Put undefined to clear the error state.
* @param target The targeted state class
* @param error The error that describes the error state
*/
constructor(target, error) {
return generateActionObject(EntityActionType.SetError, target, error);
}
}
class Reset {
/**
* Resets the targeted store to the default state: no entities, loading is false, error is undefined, active is undefined.
* @param target The targeted state class
* @see defaultEntityState
*/
constructor(target) {
return generateActionObject(EntityActionType.Reset, target);
}
}
class GoToPage {
/**
* Generates an action that changes the page index for pagination.
* Page index starts at 0.
* @param target The targeted state class
* @param payload Payload to change the page index
*/
constructor(target, payload) {
return generateActionObject(EntityActionType.GoToPage, target, Object.assign({ wrap: false }, payload));
}
}
class SetPageSize {
/**
* Generates an action that changes the page size
* @param target The targeted state class
* @param payload The page size
*/
constructor(target, payload) {
return generateActionObject(EntityActionType.SetPageSize, target, payload);
}
}
/**
* Adds or replaces the given entities to the state.
* For each entity an ID will be calculated, based on the given provider.
* This operator ensures that the calculated ID is added to the entity, at the specified id-field.
* The `lastUpdated` timestamp will be updated.
* @param entities the new entities to add or replace
* @param idKey key of the id-field of an entity
* @param idProvider function to provide an ID for the given entity
*/
function addOrReplace(entities, idKey, idProvider) {
return (state) => {
const nextEntities = Object.assign({}, state.entities);
const nextIds = [...state.ids];
let nextState = state; // will be reassigned while looping over new entities
asArray(entities).forEach(entity => {
const id = idProvider(entity, nextState);
let updatedEntity = entity;
if (entity[idKey] !== id) {
// ensure ID is in the entity
updatedEntity = Object.assign(Object.assign({}, entity), { [idKey]: id });
}
nextEntities[id] = updatedEntity;
if (!nextIds.includes(id)) {
nextIds.push(id);
}
nextState = Object.assign(Object.assign({}, nextState), { entities: nextEntities, ids: nextIds });
});
return Object.assign(Object.assign({}, nextState), { entities: nextEntities, ids: nextIds, lastUpdated: Date.now() });
};
}
function updateTimestamp() {
return patch({
lastUpdated: Date.now()
});
}
function alsoUpdateTimestamp(operator) {
return compose(updateTimestamp(), operator);
}
/**
* Removes all entities, clears the active entity and updates the `lastUpdated` timestamp.
*/
function removeAllEntities() {
return (state) => {
return Object.assign(Object.assign({}, state), { entities: {}, ids: [], active: undefined, lastUpdated: Date.now() });
};
}
/**
* Removes the entities specified by the given IDs.
* The active entity will be cleared if included in the given IDs.
* Updates the `lastUpdated` timestamp.
* @param ids IDs to remove
*/
function removeEntities(ids) {
const entityRemoval = patch({
entities: removeEntitiesFromDictionary(ids),
ids: removeEntitiesFromArray(ids)
});
return compose(entityRemoval, clearActiveIfRemoved(ids), updateTimestamp());
}
/**
* Only clears the `active` entity, if it's included in the given array.
* All other fields will remain untouched in any case.
* @param idsForRemoval the IDs to be removed
*/
function clearActiveIfRemoved(idsForRemoval) {
return (state) => {
return Object.assign(Object.assign({}, state), { active: idsForRemoval.includes(state.active) ? undefined : state.active });
};
}
/**
* Removes the given items from the existing items, based on equality.
* @param forRemoval items to remove
*/
function removeEntitiesFromArray(forRemoval) {
return (existing) => {
return existing.filter(value => !forRemoval.includes(value));
};
}
/**
* Removes items from the dictionary, based on the given keys.
* @param keysForRemoval the keys to be removed
*/
function removeEntitiesFromDictionary(keysForRemoval) {
return (existing) => {
const clone = Object.assign({}, existing);
keysForRemoval.forEach(key => delete clone[key]);
return clone;
};
}
/**
* Updates the given entities in the state.
* Entities will be merged with the given `onUpdate` function.
* @param payload the updated entities
* @param idKey key of the id-field of an entity
* @param onUpdate update function to call on each entity
*/
function update(payload, idKey, onUpdate) {
return (state) => {
let entities = Object.assign({}, state.entities); // create copy
const affected = getAffectedValues(Object.values(entities), payload.selector, idKey);
if (typeof payload.data === 'function') {
affected.forEach(entity => {
entities = updateDictionary(entities, payload.data(entity), entity[idKey], onUpdate);
});
}
else {
affected.forEach(entity => {
entities = updateDictionary(entities, payload.data, entity[idKey], onUpdate);
});
}
return Object.assign(Object.assign({}, state), { entities, lastUpdated: Date.now() });
};
}
function updateActive(payload, idKey, onUpdate) {
return (state) => {
const { id: activeId, active } = mustGetActive(state);
const { entities } = state;
if (typeof payload === 'function') {
return Object.assign(Object.assign({}, state), { entities: updateDictionary(entities, payload(active), activeId, onUpdate), lastUpdated: Date.now() });
}
else {
return Object.assign(Object.assign({}, state), { entities: updateDictionary(entities, payload, activeId, onUpdate), lastUpdated: Date.now() });
}
};
}
function updateDictionary(entities, entity, id, onUpdate) {
if (id === undefined) {
throw new UpdateFailedError(new InvalidIdError(id));
}
const current = entities[id];
if (current === undefined) {
throw new UpdateFailedError(new NoSuchEntityError(id));
}
const updated = onUpdate(current, entity);
return Object.assign(Object.assign({}, entities), { [id]: updated });
}
function getAffectedValues(entities, selector, idKey) {
if (selector === null) {
return entities;
}
else if (typeof selector === 'function') {
return entities.filter(entity => selector(entity));
}
else {
const ids = asArray(selector);
return entities.filter(entity => ids.includes(entity[idKey]));
}
}
/**
* Returns a new object which serves as the default state.
* No entities, loading is false, error is undefined, active is undefined.
* pageSize is 10 and pageIndex is 0.
*/
function defaultEntityState(defaults = {}) {
return Object.assign({ entities: {}, ids: [], loading: false, error: undefined, active: undefined, pageSize: 10, pageIndex: 0, lastUpdated: Date.now() }, defaults);
}
// tslint:disable:member-ordering
// @dynamic
class EntityState {
constructor(storeClass, _idKey, idStrategy) {
this.idKey = _idKey;
this.storePath = storeClass[NGXS_META_KEY].path;
this.idGenerator = new idStrategy(_idKey);
this.setup(storeClass, Object.values(EntityActionType));
}
/**
* This function is called every time an entity is updated.
* It receives the current entity and a partial entity that was either passed directly or generated with a function.
* The default implementation uses the spread operator to create a new entity.
* You must override this method if your entity type does not support the spread operator.
* @see Updater
* @param current The current entity, readonly
* @param updated The new data as a partial entity
* @example
* // default behavior
* onUpdate(current: Readonly<T updated: Partial<T>): T {
return {...current, ...updated};
}
*/
onUpdate(current, updated) {
return Object.assign(Object.assign({}, current), updated);
}
// ------------------- SELECTORS -------------------
/**
* Returns a selector for the activeId
*/
static get activeId() {
return createSelector([this], state => state.active);
}
/**
* Returns a selector for the active entity
*/
static get active() {
return createSelector([this], state => getActive(state));
}
/**
* Returns a selector for the keys of all entities
*/
static get keys() {
return createSelector([this], state => {
return Object.keys(state.entities);
});
}
/**
* Returns a selector for all entities, sorted by insertion order
*/
static get entities() {
return createSelector([this], state => {
return state.ids.map(id => state.entities[id]);
});
}
/**
* Returns a selector for the nth entity, sorted by insertion order
*/
static nthEntity(index) {
return createSelector([this], state => {
const id = state.ids[index];
return state.entities[id];
});
}
/**
* Returns a selector for paginated entities, sorted by insertion order
*/
static get paginatedEntities() {
return createSelector([this], state => {
const { ids, pageIndex, pageSize } = state;
return ids
.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize)
.map(id => state.entities[id]);
});
}
/**
* Returns a selector for the map of entities
*/
static get entitiesMap() {
return createSelector([this], state => {
return state.entities;
});
}
/**
* Returns a selector for the size of the entity map
*/
static get size() {
return createSelector([this], state => {
return Object.keys(state.entities).length;
});
}
/**
* Returns a selector for the error
*/
static get error() {
return createSelector([this], state => {
return state.error;
});
}
/**
* Returns a selector for the loading state
*/
static get loading() {
return createSelector([this], state => {
return state.loading;
});
}
/**
* Returns a selector for the latest added entity
*/
static get latest() {
return createSelector([this], state => {
const latestId = state.ids[state.ids.length - 1];
return state.entities[latestId];
});
}
/**
* Returns a selector for the latest added entity id
*/
static get latestId() {
return createSelector([this], state => {
return state.ids[state.ids.length - 1];
});
}
/**
* Returns a selector for the update timestamp
*/
static get lastUpdated() {
return createSelector([this], state => {
return new Date(state.lastUpdated);
});
}
/**
* Returns a selector for age, based on the update timestamp
*/
static get age() {
return createSelector([this], state => {
return Date.now() - state.lastUpdated;
});
}
// ------------------- ACTION HANDLERS -------------------
/**
* The entities given by the payload will be added.
* For certain ID strategies this might fail, if it provides an existing ID.
* In all cases it will overwrite the ID value in the entity with the calculated ID.
*/
add({ setState }, { payload }) {
setState(addOrReplace(payload, this.idKey, (entity, state) => this.idGenerator.generateId(entity, state)));
}
/**
* The entities given by the payload will be added.
* It first checks if the ID provided by each entity does exist.
* If it does the current entity will be replaced.
* In all cases it will overwrite the ID value in the entity with the calculated ID.
*/
createOrReplace({ setState }, { payload }) {
setState(addOrReplace(payload, this.idKey, (entity, state) => this.idGenerator.getPresentIdOrGenerate(entity, state)));
}
update({ setState }, { payload }) {
if (payload.selector == null) {
throw new InvalidEntitySelectorError(payload);
}
setState(update(payload, this.idKey, (current, updated) => this.onUpdate(current, updated)));
}
updateAll({ setState }, { payload }) {
setState(update(Object.assign(Object.assign({}, payload), { selector: null }), this.idKey, (current, updated) => this.onUpdate(current, updated)));
}
updateActive({ setState }, { payload }) {
setState(updateActive(payload, this.idKey, (current, updated) => this.onUpdate(current, updated)));
}
removeActive({ getState, setState }) {
const { active } = getState();
setState(removeEntities([active]));
}
remove({ getState, setState, patchState }, { payload }) {
if (payload === null) {
throw new InvalidEntitySelectorError(payload);
}
else {
const deleteIds = typeof payload === 'function'
? Object.values(getState().entities)
.filter(entity => payload(entity))
.map(entity => this.idOf(entity))
: asArray(payload);
// can't pass in predicate as you need IDs and thus EntityState#idOf
setState(removeEntities(deleteIds));
}
}
removeAll({ setState }) {
setState(removeAllEntities());
}
reset({ setState }) {
setState(defaultEntityState());
}
setLoading({ patchState }, { payload }) {
patchState({ loading: payload });
}
setActive({ patchState }, { payload }) {
patchState({ active: payload });
}
clearActive({ patchState }) {
patchState({ active: undefined });
}
setError({ patchState }, { payload }) {
patchState({ error: payload });
}
goToPage({ getState, patchState }, { payload }) {
if ('page' in payload) {
patchState({ pageIndex: payload.page });
return;
}
else if (payload['first']) {
patchState({ pageIndex: 0 });
return;
}
const { pageSize, pageIndex, ids } = getState();
const totalSize = ids.length;
const maxIndex = Math.floor(totalSize / pageSize);
if ('last' in payload) {
patchState({ pageIndex: maxIndex });
}
else {
const step = payload['prev'] ? -1 : 1;
let index = pageIndex + step;
index = wrapOrClamp(payload.wrap, index, 0, maxIndex);
patchState({ pageIndex: index });
}
}
setPageSize({ patchState }, { payload }) {
patchState({ pageSize: payload });
}
// ------------------- UTILITY -------------------
setup(storeClass, actions) {
// validation if a matching action handler exists has moved to reflection-validation tests
actions.forEach(fn => {
const actionName = `[${this.storePath}] ${fn}`;
storeClass[NGXS_META_KEY].actions[actionName] = [
{
fn: fn,
options: {},
type: actionName
}
];
});
}
/**
* Returns the id of the given entity, based on the defined idKey.
* This methods allows Partial entities and thus might return undefined.
* Other methods calling this one have to handle this case themselves.
* @param data a partial entity
*/
idOf(data) {
return data[this.idKey];
}
}
var IdStrategy;
(function (IdStrategy) {
class IdGenerator {
constructor(idKey) {
this.idKey = idKey;
}
/**
* Checks if the given id is in the state's ID array
* @param id the ID to check
* @param state the current state
*/
isIdInState(id, state) {
return state.ids.includes(id);
}
/**
* This function tries to get the present ID of the given entity with #getIdOf.
* If it's undefined the #generateId function will be used.
* @param entity The entity to get the ID from
* @param state The current state
* @see getIdOf
* @see generateId
*/
getPresentIdOrGenerate(entity, state) {
const presentId = this.getIdOf(entity);
return presentId === undefined ? this.generateId(entity, state) : presentId;
}
/**
* A wrapper for #getIdOf. If the function returns undefined an error will be thrown.
* @param entity The entity to get the ID from
* @see getIdOf
* @see InvalidIdOfError
*/
mustGetIdOf(entity) {
const id = this.getIdOf(entity);
if (id === undefined) {
throw new InvalidIdOfError();
}
return id;
}
/**
* Returns the ID for the given entity. Can return undefined.
* @param entity The entity to get the ID from
*/
getIdOf(entity) {
return entity[this.idKey];
}
}
IdStrategy.IdGenerator = IdGenerator;
class IncrementingIdGenerator extends IdGenerator {
constructor(idKey) {
super(idKey);
}
generateId(entity, state) {
const max = Math.max(-1, ...state.ids.map(id => parseInt(id, 10)));
return (max + 1).toString(10);
}
}
IdStrategy.IncrementingIdGenerator = IncrementingIdGenerator;
class UUIDGenerator extends IdGenerator {
constructor(idKey) {
super(idKey);
}
generateId(entity, state) {
let nextId;
do {
nextId = this.uuidv4();
} while (this.isIdInState(nextId, state));
return nextId;
}
uuidv4() {
// https://stackoverflow.com/a/2117523
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0; // tslint:disable-line
const v = c === 'x' ? r : (r & 0x3) | 0x8; // tslint:disable-line
return v.toString(16);
});
}
}
IdStrategy.UUIDGenerator = UUIDGenerator;
class EntityIdGenerator extends IdGenerator {
constructor(idKey) {
super(idKey);
}
generateId(entity, state) {
const id = this.mustGetIdOf(entity);
if (this.isIdInState(id, state)) {
throw new UnableToGenerateIdError(`The provided ID already exists: ${id}`);
}
return id;
}
}
IdStrategy.EntityIdGenerator = EntityIdGenerator;
})(IdStrategy || (IdStrategy = {}));
const ofEntityAction = (state, actionType) => {
const statePath = state[NGXS_META_KEY].path;
const type = `[${statePath}] ${actionType}`;
return ofAction({
type: type
});
};
const ofEntityActionDispatched = (state, actionType) => {
const statePath = state[NGXS_META_KEY].path;
const type = `[${statePath}] ${actionType}`;
return ofActionDispatched({
type: type
});
};
const ofEntityActionSuccessful = (state, actionType) => {
const statePath = state[NGXS_META_KEY].path;
const type = `[${statePath}] ${actionType}`;
return ofActionSuccessful({
type: type
});
};
const ofEntityActionErrored = (state, actionType) => {
const statePath = state[NGXS_META_KEY].path;
const type = `[${statePath}] ${actionType}`;
return ofActionErrored({
type: type
});
};
const ofEntityActionCompleted = (state, actionType) => {
const statePath = state[NGXS_META_KEY].path;
const type = `[${statePath}] ${actionType}`;
return ofActionCompleted({
type: type
});
};
// there are no cancelable actions, thus there is no need for a ofEntityActionCanceled action handler
/**
* Generated bundle index. Do not edit.
*/
export { Add, ClearActive, CreateOrReplace, EntityActionType, EntityState, EntityStateError, GoToPage, IdStrategy, InvalidEntitySelectorError, InvalidIdError, InvalidIdOfError, NoActiveEntityError, NoSuchEntityError, Remove, RemoveActive, RemoveAll, Reset, SetActive, SetError, SetLoading, SetPageSize, UnableToGenerateIdError, Update, UpdateActive, UpdateAll, UpdateFailedError, addOrReplace, alsoUpdateTimestamp, clearActiveIfRemoved, defaultEntityState, ofEntityAction, ofEntityActionCompleted, ofEntityActionDispatched, ofEntityActionErrored, ofEntityActionSuccessful, removeAllEntities, removeEntities, removeEntitiesFromArray, removeEntitiesFromDictionary, update, updateActive, updateDictionary, updateTimestamp };
//# sourceMappingURL=ngxs-labs-entity-state.js.map