plain-immutable
Version:
Make plain json data(array and object) immutable
184 lines (143 loc) • 5.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = makeArrayImmutable;
var _ = require('.');
var _2 = _interopRequireDefault(_);
var _tag = require('./tag');
var _set = require('./set');
var _remove = require('./remove');
var _merge = require('./merge');
var _merge2 = _interopRequireDefault(_merge);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function makeArrayImmutable(arr) {
if ((0, _tag.isImmutable)(arr)) return arr;
_tag.setImmutableTag.call(arr);
// deeply make value immutable
arr.forEach(function (item, index) {
(0, _2.default)(item);
});
makeMethodsImmutable.call(arr);
addNewMethods.call(arr);
return Object.freeze(arr);
} /* eslint prefer-rest-params: off */
function mutable() {
var _this = this;
if (!(0, _tag.isImmutable)(this)) return this;
var result = [];
this.forEach(function (item, index) {
result[index] = _this[index];
});
// addNewMethods.call(result);
return result;
}
function addNewMethods() {
Object.defineProperties(this, {
mutable: { value: mutable },
asMutable: { value: mutable },
set: { value: _set.set },
setIn: { value: _set.setIn },
remove: { value: _remove.remove },
delete: { value: _remove.remove },
removeIn: { value: _remove.removeIn },
deleteIn: { value: _remove.removeIn },
merge: { value: _merge2.default }
});
}
var _Array$prototype = Array.prototype,
_map = _Array$prototype.map,
_filter = _Array$prototype.filter,
_slice = _Array$prototype.slice,
_concat = _Array$prototype.concat,
_reduce = _Array$prototype.reduce,
_reduceRight = _Array$prototype.reduceRight,
_push = _Array$prototype.push,
_pop = _Array$prototype.pop,
_shift = _Array$prototype.shift,
_unshift = _Array$prototype.unshift,
_sort = _Array$prototype.sort,
_reverse = _Array$prototype.reverse,
_splice = _Array$prototype.splice,
_copyWithin = _Array$prototype.copyWithin,
_fill = _Array$prototype.fill;
// The replacement methods for array. Use named function to
// keep right function name in the error stack
var REPLACEMENTS = {};
// Make non-mutation methods that does not surely return literal value
// to return immutable value, like slice()
// =================== start: non-mutation methods =================
_slice && (REPLACEMENTS.slice = function slice() {
return makeArrayImmutable(_slice.apply(this, arguments));
});
_map && (REPLACEMENTS.map = function map() {
return makeArrayImmutable(_map.apply(this, arguments));
});
_filter && (REPLACEMENTS.filter = function filter() {
return makeArrayImmutable(_filter.apply(this, arguments));
});
_concat && (REPLACEMENTS.concat = function concat() {
return makeArrayImmutable(_concat.apply(this, arguments));
});
_reduce && (REPLACEMENTS.reduce = function reduce() {
return (0, _2.default)(_reduce.apply(this, arguments));
});
_reduceRight && (REPLACEMENTS.reduceRight = function reduceRight() {
return (0, _2.default)(_reduceRight.apply(this, arguments));
});
// =================== end: non-mutation methods =================
// Make mutation methods to return a new immutable copy
// =================== start: mutation methods =================
_push && (REPLACEMENTS.push = function push() {
var newThis = this.mutable();
_push.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_pop && (REPLACEMENTS.pop = function pop() {
var newThis = this.mutable();
_pop.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_shift && (REPLACEMENTS.shift = function shift() {
var newThis = this.mutable();
_shift.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_unshift && (REPLACEMENTS.unshift = function unshift() {
var newThis = this.mutable();
_unshift.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_sort && (REPLACEMENTS.sort = function sort() {
var newThis = this.mutable();
_sort.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_fill && (REPLACEMENTS.fill = function fill() {
var newThis = this.mutable();
_fill.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_splice && (REPLACEMENTS.splice = function splice() {
var newThis = this.mutable();
_splice.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_reverse && (REPLACEMENTS.reverse = function reverse() {
var newThis = this.mutable();
_reverse.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
_copyWithin && (REPLACEMENTS.copyWithin = function copyWithin() {
var newThis = this.mutable();
_copyWithin.apply(newThis, arguments);
return makeArrayImmutable(newThis);
});
// =================== end: mutation methods =================
var PROPERTIES = Object.keys(REPLACEMENTS).reduce(function (result, method) {
result[method] = { value: REPLACEMENTS[method] };
return result;
}, {});
function makeMethodsImmutable() {
Object.defineProperties(this, PROPERTIES);
}