@aricma/itemids
Version:
Be faster in creating and updating react state, with the ItemIds object.
187 lines (145 loc) • 5.78 kB
JavaScript
import * as ERRORS from "../errors";
import * as staticMethods from '../staticMethods';
/**
* @typedef {( string | number )} ItemId
*/
/**
* @typedef {Array.<ItemId>} ItemIdList
*/
/**
* @callback Reducer
* @param {ItemIdList} boundArray
* @return {ItemIdList} - the new values for th boundArray
*/
/**
* @param {( ItemIdList | Reducer )} action
* @return {ItemIdList}
*/
export function set(action = []) {
const isNotBoundToAnArray = !Array.isArray(this);
if (isNotBoundToAnArray) throw Error(ERRORS.methods.set.isNotBoundToAnArray);
const isItemIdList = staticMethods.isItemIdList(action);
const isFunction = typeof action === "function";
const gotNeitherItemIdListNorFunction = !isItemIdList && !isFunction;
if (gotNeitherItemIdListNorFunction) throw Error(ERRORS.methods.set.gotNeitherItemIdListNorFunction);
let values = action;
if (isFunction) values = action(this);
values = staticMethods.unify(values);
this.splice(0);
values.forEach(itemId => this.push(itemId));
return this
}
/**
* @param {( ItemId | ItemIdList )} value
* @return {ItemIdList}
*/
export function add(value = []) {
const isNotBoundToAnArray = !Array.isArray(this);
if (isNotBoundToAnArray) throw Error(ERRORS.methods.add.isNotBoundToAnArray);
const isItemId = staticMethods.isItemId(value);
const isItemIdList = staticMethods.isItemIdList(value);
const gotNeitherItemIdNorItemIdList = !isItemId && !isItemIdList;
if (gotNeitherItemIdNorItemIdList) throw Error(ERRORS.methods.add.gotNeitherItemIdNorItemIdList);
let values = value;
if (isItemId) values = [value];
values.forEach(itemId => {
const isNotInBoundArray = !this.includes(itemId);
if (isNotInBoundArray) this.push(itemId)
});
return this
}
/**
* @param {( ItemId | ItemIdList )} value
* @return {ItemIdList}
*/
export function remove(value = []) {
const isNotBoundToAnArray = !Array.isArray(this);
if (isNotBoundToAnArray) throw Error(ERRORS.methods.remove.isNotBoundToAnArray);
const isItemId = staticMethods.isItemId(value);
const isItemIdList = staticMethods.isItemIdList(value);
const gotNeitherItemIdNorItemIdList = !isItemId && !isItemIdList;
if (gotNeitherItemIdNorItemIdList) throw Error(ERRORS.methods.remove.gotNeitherItemIdNorItemIdList);
let values = value;
if (isItemId) values = [value];
values.forEach(itemId => {
const index = this.indexOf(itemId);
const isRemovable = index > -1;
if (isRemovable) this.splice(index, 1)
});
return this
}
/**
* @param {( ItemId | ItemIdList )} value
* @return {ItemIdList}
*/
export function toggle(value = []) {
const isNotBoundToAnArray = !Array.isArray(this);
if (isNotBoundToAnArray) throw Error(ERRORS.methods.toggle.isNotBoundToAnArray);
const isItemId = staticMethods.isItemId(value);
const isItemIdList = staticMethods.isItemIdList(value);
const gotNeitherItemIdNorItemIdList = !isItemId && !isItemIdList;
if (gotNeitherItemIdNorItemIdList) throw Error(ERRORS.methods.toggle.gotNeitherItemIdNorItemIdList);
let values = value;
if (isItemId) values = [value];
values.forEach(itemId => {
const isPartOfBoundArray = this.includes(itemId);
if (isPartOfBoundArray) {
const index = this.indexOf(itemId);
this.splice(index, 1)
} else {
this.push(itemId)
}
});
return this
}
/**
* @param {ItemIdList} values
* @return {ItemIdList}
*/
export function toggleAll(values = []) {
const isNotBoundToAnArray = !Array.isArray(this);
if (isNotBoundToAnArray) throw Error(ERRORS.methods.toggleAll.isNotBoundToAnArray);
const gotNoItemIdList = !staticMethods.isItemIdList(values);
if (gotNoItemIdList) throw Error(ERRORS.methods.toggleAll.gotNoItemIdList);
values = staticMethods.unify(values);
const givenAndBoundArrayHaveNotTheSameLength = this.length !== values.length;
const notAllGivenIdsAreInBoundArray = !values.reduce((hasIds, id) => hasIds && this.includes(id), true);
const needsOverwrite = givenAndBoundArrayHaveNotTheSameLength || notAllGivenIdsAreInBoundArray;
this.splice(0);
if (needsOverwrite) values.forEach(itemId => this.push(itemId));
return this
}
/**
* @param {( ItemId | ItemIdList )} value
* @return {boolean}
*/
export function has(value = []) {
const isNotBoundToAnArray = !Array.isArray(this);
if (isNotBoundToAnArray) throw Error(ERRORS.methods.has.isNotBoundToAnArray);
const isItemId = staticMethods.isItemId(value);
const isItemIdList = staticMethods.isItemIdList(value);
const gotNeitherItemIdNorItemIdList = !isItemId && !isItemIdList;
if (gotNeitherItemIdNorItemIdList) throw Error(ERRORS.methods.has.gotNeitherItemIdNorItemIdList);
let result = false;
let values = value;
if (isItemId) values = [value];
const givenWasNoEmptyArray = values.length > 0;
if (givenWasNoEmptyArray) result = values.reduce((hasIds, itemId) => hasIds && this.includes(itemId), true);
return result
}
/**
* @param {ItemIdList} values
* @return {boolean}
*/
export function isEqualTo(values) {
const isNotBoundToAnArray = !Array.isArray(this);
if (isNotBoundToAnArray) throw Error(ERRORS.methods.isEqualTo.isNotBoundToAnArray);
const gotNoItemIdList = !staticMethods.isItemIdList(values);
if (gotNoItemIdList) throw Error(ERRORS.methods.isEqualTo.gotNoItemIdList);
let result = false;
const boundAndGivenArrayHavenTheSameLength = this.length === values.length;
if (boundAndGivenArrayHavenTheSameLength) {
result = values.reduce((hasIds, itemId) => hasIds && this.includes(itemId), true);
}
return result
}