UNPKG

@ngxs/store

Version:
191 lines (180 loc) 6.2 kB
const isArray = Array.isArray; const isFunction = (value) => typeof value == 'function'; const isStateOperator = isFunction; const isPredicate = isFunction; const isNumber = (value) => typeof value === 'number'; const invalidIndex = (index) => Number.isNaN(index) || index === -1; /** * @param items - Specific items to append to the end of an array */ function append(items) { return function appendOperator(existing) { // If `items` is `undefined` or `null` or `[]` but `existing` is provided // just return `existing` const itemsNotProvidedButExistingIs = (!items || !items.length) && existing; if (itemsNotProvidedButExistingIs) { return existing; } if (isArray(existing)) { return existing.concat(items); } // For example if some property is added dynamically // and didn't exist before thus it's not `ArrayLike` return items; }; } function compose(...operators) { return function composeOperator(existing) { return operators.reduce((accumulator, operator) => operator(accumulator), existing); }; } function retrieveValue(operatorOrValue, existing) { // If state operator is a function // then call it with an original value if (isStateOperator(operatorOrValue)) { const value = operatorOrValue(existing); return value; } // If operator or value was not provided // e.g. `elseOperatorOrValue` is `undefined` // then we just return an original value if (operatorOrValue === undefined) { return existing; } return operatorOrValue; } /** * @param condition - Condition can be a plain boolean value or a function, * that returns boolean, also this function can take a value as an argument * to which this state operator applies * @param trueOperatorOrValue - Any value or a state operator * @param elseOperatorOrValue - Any value or a state operator */ function iif(condition, trueOperatorOrValue, elseOperatorOrValue) { return function iifOperator(existing) { // Convert the value to a boolean let result = !!condition; // but if it is a function then run it to get the result if (isPredicate(condition)) { result = condition(existing); } if (result) { return retrieveValue(trueOperatorOrValue, existing); } return retrieveValue(elseOperatorOrValue, existing); }; } /** * @param value - Value to insert * @param [beforePosition] - Specified index to insert value before, optional */ function insertItem(value, beforePosition) { return function insertItemOperator(existing) { // Have to check explicitly for `null` and `undefined` // because `value` can be `0`, thus `!value` will return `true` if (value == null && existing) { return existing; } // Property may be dynamic and might not existed before if (!isArray(existing)) { return [value]; } const clone = existing.slice(); let index = 0; // No need to call `isNumber` // as we are checking `> 0` not `>= 0` // everything except number will return false here if (beforePosition > 0) { index = beforePosition; } clone.splice(index, 0, value); return clone; }; } function patch(patchObject) { return function patchStateOperator(existing) { let clone = null; for (const k in patchObject) { const newValue = patchObject[k]; const existingPropValue = existing?.[k]; const newPropValue = isStateOperator(newValue) ? newValue(existingPropValue) : newValue; if (newPropValue !== existingPropValue) { if (!clone) { clone = { ...existing }; } clone[k] = newPropValue; } } return clone || existing; }; } /** * @param selector - Index of item in the array or a predicate function * that can be provided in `Array.prototype.findIndex` * @param operatorOrValue - New value under the `selector` index or a * function that can be applied to an existing value */ function updateItem(selector, operatorOrValue) { return function updateItemOperator(existing) { let index = -1; if (isPredicate(selector)) { index = existing.findIndex(selector); } else if (isNumber(selector)) { index = selector; } if (invalidIndex(index)) { return existing; } let value = null; // Need to check if the new item value will change the existing item value // then, only if it will change it then clone the array and set the item const theOperatorOrValue = operatorOrValue; if (isStateOperator(theOperatorOrValue)) { value = theOperatorOrValue(existing[index]); } else { value = theOperatorOrValue; } // If the value hasn't been mutated // then we just return `existing` array if (value === existing[index]) { return existing; } const clone = existing.slice(); clone[index] = value; return clone; }; } /** * @param selector - index or predicate to remove an item from an array by */ function removeItem(selector) { return function removeItemOperator(existing) { let index = -1; if (isPredicate(selector)) { index = existing.findIndex(selector); } else if (isNumber(selector)) { index = selector; } if (invalidIndex(index)) { return existing; } const clone = existing.slice(); clone.splice(index, 1); return clone; }; } /** * @module * @description * Entry point for all public APIs of this package. */ /** * Generated bundle index. Do not edit. */ export { append, compose, iif, insertItem, isPredicate, isStateOperator, patch, removeItem, updateItem }; //# sourceMappingURL=ngxs-store-operators.mjs.map