@mic-rexjs/usecases-react
Version:
React-based solution for use usecases of Clean Architecture
168 lines • 5.52 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import { createUseCase, entityUseCase, utilsUseCase } from '@mic-rexjs/usecases';
export const valueUseCase = createUseCase(() => {
return () => {
const entityReducers = entityUseCase();
const _utilsUseCase = utilsUseCase(),
createKey = _utilsUseCase.createKey;
let prevKeyIndex = createKey();
const isObjectValue = entity => {
if (typeof entity !== 'object' || entity === null) {
return false;
}
return true;
};
const hasField = (entity, field) => {
const isObject = isObjectValue(entity);
if (isObject) {
return Object.hasOwn(entity, field);
}
return false;
};
const isValueChanged = (entity, value) => {
return entity !== value;
};
const matchValue = (entity, value, onMatchPropertyFailed) => {
if (entity === value) {
return true;
}
const isObject1 = isObjectValue(entity);
const isObject2 = isObjectValue(value);
const keys1 = isObject1 ? Object.keys(entity) : [];
const keys2 = isObject2 ? Object.keys(value) : [];
const hasCallback = typeof onMatchPropertyFailed === 'function';
if (!isObject1 && !isObject2) {
return false;
}
let allMatched = true;
const length1 = keys1.length;
const keys = [...keys1, ...keys2];
for (let i = 0, length = keys.length; i < length; i++) {
const key = keys[i];
const isInKey1 = keys1.includes(key);
const isFromKeys2 = i >= length1;
const isUsed = isFromKeys2 && isInKey1;
if (isUsed) {
continue;
}
const hasField1 = hasField(entity, key);
const hasField2 = hasField(value, key);
const value1 = hasField1 ? entity[key] : void 0;
const value2 = hasField2 ? value[key] : void 0;
const matched = value1 === value2;
if (hasField1 && hasField2 && matched) {
continue;
}
allMatched = false;
if (hasCallback) {
onMatchPropertyFailed(key, value2, value1);
continue;
}
break;
}
return allMatched;
};
const matchProperty = (entity, value, fieldPath, onFailed) => {
let allMatched = true;
let currentFieldPath = fieldPath;
const list = [{
fieldPaths: [],
newEntity: value,
newValue: value,
oldEntity: entity,
oldValue: entity
}];
do {
const _list$shift = list.shift(),
oldValue = _list$shift.oldValue,
newValue = _list$shift.newValue,
fieldPaths = _list$shift.fieldPaths;
const _ref = currentFieldPath.match(/^([^.]+)\.(.+)$/) || [],
_ref2 = _slicedToArray(_ref, 3),
_ref2$ = _ref2[1],
key = _ref2$ === void 0 ? currentFieldPath : _ref2$,
_ref2$2 = _ref2[2],
subFieldPath = _ref2$2 === void 0 ? '' : _ref2$2;
const hasOldField = hasField(oldValue, key);
const hasNewField = hasField(newValue, key);
if (hasOldField || hasNewField) {
const _ref3 = hasOldField ? [oldValue[key]] : [],
_ref4 = _slicedToArray(_ref3, 1),
oldSubValue = _ref4[0];
const _ref5 = hasNewField ? [newValue[key]] : [],
_ref6 = _slicedToArray(_ref5, 1),
newSubValue = _ref6[0];
const result = {
fieldPaths: [...fieldPaths, key],
newEntity: value,
newValue: newSubValue,
oldEntity: entity,
oldValue: oldSubValue
};
if (subFieldPath) {
currentFieldPath = subFieldPath;
list.push(result);
continue;
}
if (newSubValue === oldSubValue) {
continue;
}
allMatched = false;
onFailed === null || onFailed === void 0 || onFailed(result);
continue;
}
if (/^\d+^/.test(key)) {
continue;
}
const oldArray = Array.isArray(oldValue) ? oldValue : [];
const newArray = Array.isArray(newValue) ? newValue : [];
const oldLength = oldArray.length;
const newLength = newArray.length;
const length = Math.max(oldLength, newLength);
for (let i = 0; i < length; i++) {
list.push({
fieldPaths: [...fieldPaths, `${i}`],
newEntity: value,
newValue: newArray[i],
oldEntity: entity,
oldValue: oldArray[i]
});
}
} while (list.length > 0);
return allMatched;
};
const recordValue = function* (entity, value) {
const changed = isValueChanged(entity, value);
if (!changed) {
return false;
}
yield value;
return true;
};
const recordValueMatch = function* (entity, value) {
const matched = matchValue(entity, value);
if (matched) {
return true;
}
yield value;
return false;
};
const recordValueMatchWith = function* (entity, value, key) {
const matched = yield* recordValueMatch(entity, value);
if (!matched) {
prevKeyIndex = key !== null && key !== void 0 ? key : createKey();
}
return prevKeyIndex;
};
return {
...entityReducers,
isObjectValue,
isValueChanged,
matchValue,
matchProperty,
recordValue,
recordValueMatch,
recordValueMatchWith
};
};
});