plain-immutable
Version:
Make plain json data(array and object) immutable
75 lines (59 loc) • 2.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
exports.setIn = setIn;
exports.set = set;
exports.recursivelySet = recursivelySet;
var _index = require('./index');
var _index2 = _interopRequireDefault(_index);
var _util = require('./util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Set the value at leaf key of key path. if any key is not existent, create an object.
* @param keyPath string|array.
* @param value json|immutable|function.
*/
function setIn(keyPath, value) {
if (!Array.isArray(keyPath)) keyPath = [keyPath];
return recursivelySet.call(this, keyPath, 0, value);
}
function set(key, value) {
key = (0, _util.validateKey)(key);
return recursivelySet.call(this, [key], 0, value);
}
function recursivelySet(keyPath, ii, value, breakOnNonExistentKey) {
var key = (0, _util.validateKeyInKeyPath)(keyPath, keyPath[ii]);
// if key not existent, return immediately, see removeIn()
var hasKey = this.hasOwnProperty(key);
if (breakOnNonExistentKey && !hasKey) return this;
var oldValue = this[key];
if (keyPath.length - 1 > ii) {
// has sub keys, try to call set recursively
if (hasKey) {
if (!oldValue || (typeof oldValue === 'undefined' ? 'undefined' : _typeof(oldValue)) !== 'object') {
var position = (0, _util.stringify)(keyPath.slice(0, ii + 1));
throw new TypeError('Cannot update on non-object value at ' + position + ': ' + (0, _util.stringify)(oldValue));
}
value = recursivelySet.call(oldValue, keyPath, ii + 1, value, breakOnNonExistentKey);
} else {
// for nonexistent key, create an object first
value = recursivelySet.call((0, _index2.default)({}), keyPath, ii + 1, value, breakOnNonExistentKey);
}
} else if (typeof value === 'function') {
// update key value by function(setter)
var setter = value;
value = (0, _index2.default)(setter(oldValue));
} else {
value = (0, _index2.default)(value);
}
// if key is not existent, value will always be set
if (!this.hasOwnProperty(key) || value !== oldValue) {
var newThis = this.mutable();
newThis[key] = value;
return (0, _index2.default)(newThis);
}
// no change
return this;
}