data-cursor
Version:
Javascript Library to traverse nested structures and modify in place without mutating data
130 lines (98 loc) • 4.02 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getCursor;
var _Operations = require('./Operations');
var CURSOR_SYMBOL = '@@IS_CURSOR' + Math.random();
var isOperationInProcess = false;
var currentOperationName = '';
var operationPath = null;
var initialOperationArgs = null;
function _getCursor(currentValue, operations, changeParentProperty, transactionDescriptor, currentPathKey, isRoot) {
var mutableValue = null;
var mutableValueCreated = false;
var isSetMutableValueToParent = false;
function checkTransactionState() {
if (transactionDescriptor.isClosed) {
throw new Error('Cursor is closed becauze transaction ended');
}
}
var childChangeParentProperty = function childChangeParentProperty(key, newValue, prevValue) {
if (cursor.get(key).value() === prevValue) {
cursor.set(key, newValue);
}
};
function getMutableValue() {
if (!mutableValueCreated) {
mutableValue = operations.getMutableVersionForValue(currentValue);
mutableValueCreated = true;
}
return mutableValue;
}
var lastSetValue = currentValue;
var operators = operations.getOperatorsForValue(currentValue);
function getNestedCursor(keyPath, value) {
return _getCursor(value, operations, childChangeParentProperty, transactionDescriptor, keyPath, false);
}
function updateMutableValue(newValue) {
mutableValue = operations.getMutableVersionForValue(newValue);
mutableValueCreated = true;
return mutableValue;
}
function changeThisInParent(newValue) {
if (isRoot) {
changeParentProperty(newValue, lastSetValue, operationPath, currentOperationName, initialOperationArgs);
} else {
changeParentProperty(currentPathKey, newValue, lastSetValue, operationPath, currentOperationName, initialOperationArgs);
}
}
var cursor = operators.reduce(function (accum, _ref) {
var key = _ref.key;
var value = _ref.value;
accum[key] = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (!isOperationInProcess) {
checkTransactionState();
isOperationInProcess = true;
initialOperationArgs = args;
currentOperationName = key;
operationPath = [];
}
if (!isRoot) {
operationPath.push(currentPathKey);
}
var result = value({
cursor: cursor,
args: args,
getNestedCursor: getNestedCursor,
getMutableValue: getMutableValue,
updateMutableValue: updateMutableValue,
changeThisInParent: changeThisInParent,
getValue: function getValue() {
return mutableValueCreated ? mutableValue : currentValue;
}
});
isOperationInProcess = false;
initialOperationArgs = null;
operationPath = null;
currentOperationName = '';
return result;
};
return accum;
}, {});
Object.defineProperty(cursor, CURSOR_SYMBOL, {
value: true,
writable: false,
enumerable: false
});
return cursor;
}
function getCursor(currentValue) {
var operations = arguments.length <= 1 || arguments[1] === undefined ? _Operations.defaultOperations : arguments[1];
var changeParentProperty = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2];
var transactionDescriptor = arguments.length <= 3 || arguments[3] === undefined ? { isClosed: false } : arguments[3];
return _getCursor(currentValue, operations, changeParentProperty, transactionDescriptor, '', true);
}
;