immutable-set
Advanced tools
Comparing version 2.0.0 to 2.1.0
@@ -9,8 +9,10 @@ 'use strict'; | ||
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; }; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
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.default = safeSet; | ||
var _utils = require('./utils'); | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
@@ -21,26 +23,2 @@ | ||
/** | ||
* Recursive equality tester. Return true if the top down element of the path in the base is equal to the given value | ||
* @param base current base | ||
* @param path current path | ||
* @param value value to verify | ||
* @param equality override the equality assertion | ||
* @returns {boolean} true if the value is in the base at the end of the path | ||
*/ | ||
function recursiveEqual(base, path, value, equality) { | ||
if (!base || (typeof base === 'undefined' ? 'undefined' : _typeof(base)) !== 'object') { | ||
return false; | ||
} | ||
var _path = _slicedToArray(path, 2), | ||
key = _path[0], | ||
nextKey = _path[1]; | ||
if (nextKey === undefined) { | ||
return equality ? equality(base[key], value) : base[key] === value; | ||
} | ||
return recursiveEqual(base[key], path.slice(1), value, equality); | ||
} | ||
/** | ||
* Compute next base in recursion | ||
@@ -73,4 +51,7 @@ * @param base current base | ||
*/ | ||
function (base, path, keys, nextKey, values, withArrays, accumulator) { | ||
if (!Array.isArray(values)) { | ||
function (base, path, keys, nextKey, values, _ref, accumulator) { | ||
var withArrays = _ref.withArrays, | ||
sameValue = _ref.sameValue; | ||
if (!Array.isArray(values) && !sameValue) { | ||
throw new Error('Can not use object values with array in path'); | ||
@@ -80,3 +61,7 @@ } | ||
return keys.reduce(function (acc, key, index) { | ||
var newValue = setFunction(nextBase(base, key, nextKey, withArrays), path.slice(1), values[index], withArrays); | ||
var value = sameValue ? values : values[index]; | ||
var newValue = setFunction(nextBase(base, key, nextKey, withArrays), path.slice(1), value, { | ||
withArrays: withArrays, | ||
sameValue: sameValue | ||
}); | ||
@@ -111,6 +96,10 @@ if (key < acc.length) { | ||
*/ | ||
function (base, path, keys, nextKey, values, withArrays) { | ||
function (base, path, keys, nextKey, values, _ref2) { | ||
var withArrays = _ref2.withArrays, | ||
sameValue = _ref2.sameValue; | ||
if (Array.isArray(values)) { | ||
return keys.reduce(function (acc, key, index) { | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), values[index], withArrays); | ||
var value = sameValue ? values : values[index]; | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), value, { withArrays: withArrays, sameValue: sameValue }); | ||
@@ -122,3 +111,4 @@ return acc; | ||
return keys.reduce(function (acc, key) { | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), values[key], withArrays); | ||
var value = sameValue ? values : values[key]; | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), value, { withArrays: withArrays, sameValue: sameValue }); | ||
@@ -136,6 +126,11 @@ return acc; | ||
* @param value current value | ||
* @param withArrays create arrays instead of object when nextKey is a number and key has no value in the current base | ||
* @param config | ||
* - withArrays create arrays instead of object when nextKey is a number and key has no value in the current base | ||
* - sameValue use the same value for each element | ||
* @returns {*} a new instance of the given level | ||
*/ | ||
function set(base, path, value, withArrays) { | ||
function set(base, path, value, _ref3) { | ||
var withArrays = _ref3.withArrays, | ||
sameValue = _ref3.sameValue; | ||
if (path.length === 0) { | ||
@@ -145,5 +140,5 @@ return value; | ||
var _path2 = _slicedToArray(path, 2), | ||
key = _path2[0], | ||
nextKey = _path2[1]; | ||
var _path = _slicedToArray(path, 2), | ||
key = _path[0], | ||
nextKey = _path[1]; | ||
@@ -159,13 +154,13 @@ var isArrayKeys = Array.isArray(key); | ||
if (Array.isArray(currentBase)) { | ||
return reduceWithArray(set)(currentBase, path, key, nextKey, value, withArrays, [].concat(_toConsumableArray(currentBase))); | ||
return reduceWithArray(set)(currentBase, path, key, nextKey, value, { withArrays: withArrays, sameValue: sameValue }, [].concat(_toConsumableArray(currentBase))); | ||
} | ||
return _extends({}, currentBase, reduceWithObject(set)(currentBase, path, key, nextKey, value, withArrays, {})); | ||
return _extends({}, currentBase, reduceWithObject(set)(currentBase, path, key, nextKey, value, { withArrays: withArrays, sameValue: sameValue }, {})); | ||
} | ||
if (Array.isArray(currentBase)) { | ||
return [].concat(_toConsumableArray(currentBase.slice(0, key)), [set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, withArrays)], _toConsumableArray(currentBase.slice(key + 1))); | ||
return [].concat(_toConsumableArray(currentBase.slice(0, key)), [set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, { withArrays: withArrays, sameValue: sameValue })], _toConsumableArray(currentBase.slice(key + 1))); | ||
} | ||
return _extends({}, currentBase, _defineProperty({}, key, set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, withArrays))); | ||
return _extends({}, currentBase, _defineProperty({}, key, set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, { withArrays: withArrays, sameValue: sameValue }))); | ||
} | ||
@@ -186,3 +181,4 @@ | ||
equality = options.equality, | ||
safe = options.safe; | ||
_options$sameValue = options.sameValue, | ||
sameValue = _options$sameValue === undefined ? false : _options$sameValue; | ||
@@ -212,7 +208,7 @@ var path = initialPath; | ||
// If the value is already here we just need to return the base | ||
if (safe && recursiveEqual(base, path, value, equality)) { | ||
if ((0, _utils.isSafe)(value, options) && (0, _utils.recursiveEqual)(base, path, value, equality)) { | ||
return base; | ||
} | ||
return set(base, path, value, withArrays); | ||
return set(base, path, value, { withArrays: withArrays, sameValue: sameValue }); | ||
} |
{ | ||
"name": "immutable-set", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "Set nested properties of an object while respecting the principles of immutability", | ||
@@ -29,5 +29,5 @@ "main": "lib/set.js", | ||
"deep-freeze": "0.0.1", | ||
"eslint-tools-m6web": "1.1.1", | ||
"jest": "21.0.2" | ||
"eslint-tools-m6web": "1.2.0", | ||
"jest": "23.4.1" | ||
} | ||
} |
@@ -45,2 +45,3 @@ ![build status](https://travis-ci.org/M6Web/immutable-set.svg) | ||
safe | verify if the value does not already exist | boolean | false | ||
sameValue | use same value for each nested property in case of multi set | boolean | false | ||
@@ -105,2 +106,3 @@ | ||
It is possible to set multiple elements at once, providing multiple keys in the path and an array (or an object) in value. | ||
```js | ||
@@ -112,8 +114,17 @@ set({}, ['a', ['b', 'c']], [12, 13]); | ||
set({}, ['a', [0, 1 ]], [12, 13], { withArrays: true }); | ||
// will return { a: [12, 13] } | ||
``` | ||
It's also possible to set multiple elements at once with the same value by setting `sameValue: true` in options. | ||
```js | ||
set({}, ['a', ['b', 'c']], { foo: 'bar' }, { sameValue: true }); | ||
// will return { a: { b: { foo: 'bar' }, c: { foo: 'bar' } } } | ||
set({}, ['a', [0, 1 ]], 'foo', { withArrays: true, sameValue: true }); | ||
// will return { a: ['foo', 'foo'] } | ||
``` | ||
- :warning: If the array of keys is not the last element of the path, the rest of the path will be used for each sub tree. | ||
- :warning: It's not possible to set objects in array with object sub values, this will throw an error. | ||
- :warning: For now safe mode does not work with multiple set. |
@@ -1,22 +0,3 @@ | ||
/** | ||
* Recursive equality tester. Return true if the top down element of the path in the base is equal to the given value | ||
* @param base current base | ||
* @param path current path | ||
* @param value value to verify | ||
* @param equality override the equality assertion | ||
* @returns {boolean} true if the value is in the base at the end of the path | ||
*/ | ||
function recursiveEqual(base, path, value, equality) { | ||
if (!base || typeof base !== 'object') { | ||
return false; | ||
} | ||
const [key, nextKey] = path; | ||
import { recursiveEqual, isSafe } from './utils'; | ||
if (nextKey === undefined) { | ||
return equality ? equality(base[key], value) : base[key] === value; | ||
} | ||
return recursiveEqual(base[key], path.slice(1), value, equality); | ||
} | ||
/** | ||
@@ -47,4 +28,4 @@ * Compute next base in recursion | ||
*/ | ||
(base, path, keys, nextKey, values, withArrays, accumulator) => { | ||
if (!Array.isArray(values)) { | ||
(base, path, keys, nextKey, values, { withArrays, sameValue }, accumulator) => { | ||
if (!Array.isArray(values) && !sameValue) { | ||
throw new Error('Can not use object values with array in path'); | ||
@@ -54,3 +35,7 @@ } | ||
return keys.reduce((acc, key, index) => { | ||
const newValue = setFunction(nextBase(base, key, nextKey, withArrays), path.slice(1), values[index], withArrays); | ||
const value = sameValue ? values : values[index]; | ||
const newValue = setFunction(nextBase(base, key, nextKey, withArrays), path.slice(1), value, { | ||
withArrays, | ||
sameValue, | ||
}); | ||
@@ -82,6 +67,7 @@ if (key < acc.length) { | ||
*/ | ||
(base, path, keys, nextKey, values, withArrays) => { | ||
(base, path, keys, nextKey, values, { withArrays, sameValue }) => { | ||
if (Array.isArray(values)) { | ||
return keys.reduce((acc, key, index) => { | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), values[index], withArrays); | ||
const value = sameValue ? values : values[index]; | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), value, { withArrays, sameValue }); | ||
@@ -93,3 +79,4 @@ return acc; | ||
return keys.reduce((acc, key) => { | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), values[key], withArrays); | ||
const value = sameValue ? values : values[key]; | ||
acc[key] = fn(nextBase(base, key, nextKey, withArrays), path.slice(1), value, { withArrays, sameValue }); | ||
@@ -105,6 +92,8 @@ return acc; | ||
* @param value current value | ||
* @param withArrays create arrays instead of object when nextKey is a number and key has no value in the current base | ||
* @param config | ||
* - withArrays create arrays instead of object when nextKey is a number and key has no value in the current base | ||
* - sameValue use the same value for each element | ||
* @returns {*} a new instance of the given level | ||
*/ | ||
function set(base, path, value, withArrays) { | ||
function set(base, path, value, { withArrays, sameValue }) { | ||
if (path.length === 0) { | ||
@@ -124,3 +113,3 @@ return value; | ||
if (Array.isArray(currentBase)) { | ||
return reduceWithArray(set)(currentBase, path, key, nextKey, value, withArrays, [...currentBase]); | ||
return reduceWithArray(set)(currentBase, path, key, nextKey, value, { withArrays, sameValue }, [...currentBase]); | ||
} | ||
@@ -130,3 +119,3 @@ | ||
...currentBase, | ||
...reduceWithObject(set)(currentBase, path, key, nextKey, value, withArrays, {}), | ||
...reduceWithObject(set)(currentBase, path, key, nextKey, value, { withArrays, sameValue }, {}), | ||
}; | ||
@@ -138,3 +127,3 @@ } | ||
...currentBase.slice(0, key), | ||
set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, withArrays), | ||
set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, { withArrays, sameValue }), | ||
...currentBase.slice(key + 1), | ||
@@ -146,3 +135,3 @@ ]; | ||
...currentBase, | ||
[key]: set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, withArrays), | ||
[key]: set(nextBase(currentBase, key, nextKey, withArrays), path.slice(1), value, { withArrays, sameValue }), | ||
}; | ||
@@ -160,3 +149,3 @@ } | ||
export default function safeSet(base, initialPath, value, options = {}) { | ||
const { withArrays = false, equality, safe } = options; | ||
const { withArrays = false, equality, sameValue = false } = options; | ||
let path = initialPath; | ||
@@ -185,7 +174,7 @@ | ||
// If the value is already here we just need to return the base | ||
if (safe && recursiveEqual(base, path, value, equality)) { | ||
if (isSafe(value, options) && recursiveEqual(base, path, value, equality)) { | ||
return base; | ||
} | ||
return set(base, path, value, withArrays); | ||
return set(base, path, value, { withArrays, sameValue }); | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
22530
7
386
128
0