diff --git a/packages/immutadot-lodash/src/array/pull.js b/packages/immutadot-lodash/src/array/pull.js
index f82538b6..f5698a05 100644
--- a/packages/immutadot-lodash/src/array/pull.js
+++ b/packages/immutadot-lodash/src/array/pull.js
@@ -1,5 +1,5 @@
import _pull from 'lodash/fp/pull'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* Replaces an array removing all given values from the former array.
diff --git a/packages/immutadot-lodash/src/array/pullAll.js b/packages/immutadot-lodash/src/array/pullAll.js
index b7a5676f..443e3e5f 100644
--- a/packages/immutadot-lodash/src/array/pullAll.js
+++ b/packages/immutadot-lodash/src/array/pullAll.js
@@ -1,5 +1,5 @@
import _pullAll from 'lodash/fp/pullAll'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* This method is like {@link array.pull} except that it accepts an array of values to remove.
diff --git a/packages/immutadot-lodash/src/array/pullAllBy.js b/packages/immutadot-lodash/src/array/pullAllBy.js
index 8672440a..4084dee9 100644
--- a/packages/immutadot-lodash/src/array/pullAllBy.js
+++ b/packages/immutadot-lodash/src/array/pullAllBy.js
@@ -1,5 +1,5 @@
import _pullAllBy from 'lodash/fp/pullAllBy'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* This method is like {@link array.pullAll} except that it accepts iteratee
to generate the criterion by which each element is compared.
diff --git a/packages/immutadot-lodash/src/array/pullAllWith.js b/packages/immutadot-lodash/src/array/pullAllWith.js
index d7709301..81f7b7ae 100644
--- a/packages/immutadot-lodash/src/array/pullAllWith.js
+++ b/packages/immutadot-lodash/src/array/pullAllWith.js
@@ -1,5 +1,5 @@
import _pullAllWith from 'lodash/fp/pullAllWith'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* This method is like {@link array.pullAll} except that it accepts comparator
to compare elements.
diff --git a/packages/immutadot-lodash/src/array/pullAt.js b/packages/immutadot-lodash/src/array/pullAt.js
index 29b19e88..3e0e4223 100644
--- a/packages/immutadot-lodash/src/array/pullAt.js
+++ b/packages/immutadot-lodash/src/array/pullAt.js
@@ -1,5 +1,5 @@
import _pullAt from 'lodash/fp/pullAt'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* Replaces an array removing the specified indexes from the former array.
diff --git a/packages/immutadot-lodash/src/array/remove.js b/packages/immutadot-lodash/src/array/remove.js
index daa19cd8..ffd04f02 100644
--- a/packages/immutadot-lodash/src/array/remove.js
+++ b/packages/immutadot-lodash/src/array/remove.js
@@ -1,5 +1,5 @@
import _remove from 'lodash/fp/remove'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* Replaces an array removing elements that predicate returns truthy for from the former array.
diff --git a/packages/immutadot-lodash/src/object/defaults.js b/packages/immutadot-lodash/src/object/defaults.js
index c1d563c1..c0424f53 100644
--- a/packages/immutadot-lodash/src/object/defaults.js
+++ b/packages/immutadot-lodash/src/object/defaults.js
@@ -1,5 +1,5 @@
import _defaults from 'lodash/fp/defaults'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* Replaces by an object assigning own and inherited enumerable string keyed properties of source objects to the destination object for all destination properties that resolve to undefined
.
diff --git a/packages/immutadot-lodash/src/object/merge.js b/packages/immutadot-lodash/src/object/merge.js
index 018d118c..2e93ecbc 100644
--- a/packages/immutadot-lodash/src/object/merge.js
+++ b/packages/immutadot-lodash/src/object/merge.js
@@ -1,5 +1,5 @@
import _merge from 'lodash/fp/merge'
-import { convertLodashFp } from 'immutadot/util/convert'
+import { convertLodashFp } from 'util/convertLodashFp'
/**
* Replaces by an object deeply merging own enumerable string keyed properties of source objects to the former object.
diff --git a/packages/immutadot/src/util/convert.js b/packages/immutadot-lodash/src/util/convertLodashFp.js
similarity index 91%
rename from packages/immutadot/src/util/convert.js
rename to packages/immutadot-lodash/src/util/convertLodashFp.js
index 509bda54..d7b97b1c 100644
--- a/packages/immutadot/src/util/convert.js
+++ b/packages/immutadot-lodash/src/util/convertLodashFp.js
@@ -1,4 +1,4 @@
-import { convert } from 'core/convert'
+import { convert } from 'immutadot/core/convert'
import { lodashFpConvert } from './lodashFpConvert'
/**
diff --git a/packages/immutadot/src/util/lodashFpConvert.js b/packages/immutadot-lodash/src/util/lodashFpConvert.js
similarity index 100%
rename from packages/immutadot/src/util/lodashFpConvert.js
rename to packages/immutadot-lodash/src/util/lodashFpConvert.js
diff --git a/packages/immutadot/package.json b/packages/immutadot/package.json
index 60ee1a0c..0cc3ac30 100644
--- a/packages/immutadot/package.json
+++ b/packages/immutadot/package.json
@@ -29,9 +29,6 @@
"jsdoc": "^3.5.5"
},
"dependencies": {},
- "peerDependencies": {
- "lodash": "^4.17.4"
- },
"scripts": {
"generate:flow": "node ../../misc/generate-flow.js",
"prebuild": "yarn generate:flow",
diff --git a/packages/immutadot/src/array/concat.js b/packages/immutadot/src/array/concat.js
index 407ca6f9..1dc0cfea 100644
--- a/packages/immutadot/src/array/concat.js
+++ b/packages/immutadot/src/array/concat.js
@@ -1,5 +1,4 @@
-import _concat from 'lodash/concat'
-import { convert } from 'core/convert'
+import { convertArrayMethod } from './convertArrayMethod'
/**
* Replaces an array concatenating the former array with additional arrays and/or values.
@@ -14,5 +13,5 @@ import { convert } from 'core/convert'
* @since 0.2.0
* @flow
*/
-const concat = convert(_concat)
+const concat = convertArrayMethod('concat', false, true)
export { concat }
diff --git a/packages/immutadot/src/array/convertArrayMethod.js b/packages/immutadot/src/array/convertArrayMethod.js
index cdcc4e5f..d62f7e13 100644
--- a/packages/immutadot/src/array/convertArrayMethod.js
+++ b/packages/immutadot/src/array/convertArrayMethod.js
@@ -4,25 +4,39 @@ import {
isNil,
} from 'util/lang'
-const copyArray = array => {
+const toArray = array => {
+ if (isNil(array)) return []
+ if (Array.isArray(array)) return array
+ return [array]
+}
+
+const toArrayCopy = array => {
if (isNil(array)) return []
if (Array.isArray(array)) return [...array]
return [array]
}
+const callMethodReturnResult = (array, method, args) => array[method](...args)
+
+const callMethodReturnArray = (array, method, args) => {
+ array[method](...args)
+ return array
+}
+
/**
* Converts an Array method.
* @memberof array
* @param {string} method Array method name.
+ * @param {boolean} [mutating=true] Whether the method mutates the array.
* @return {function} Returns the wrapped function.
* @see {@link core.convert|convert} for more information.
* @since 0.2.0
* @private
*/
-const convertArrayMethod = method => convert((array, ...args) => {
- const newArray = copyArray(array)
- newArray[method](...args)
- return newArray
-})
+const convertArrayMethod = (method, mutating = true) => {
+ const getArray = mutating ? toArrayCopy : toArray
+ const callMethod = mutating ? callMethodReturnArray : callMethodReturnResult
+ return convert((value, ...args) => callMethod(getArray(value), method, args))
+}
export { convertArrayMethod }
diff --git a/packages/immutadot/src/array/fill.js b/packages/immutadot/src/array/fill.js
index 9763722c..a790957c 100644
--- a/packages/immutadot/src/array/fill.js
+++ b/packages/immutadot/src/array/fill.js
@@ -1,5 +1,4 @@
-import _fill from 'lodash/fp/fill'
-import { convertLodashFp } from 'util/convert'
+import { convertArrayMethod } from './convertArrayMethod'
/**
* Replaces by an array filled with value from start up to, but not including, end.
@@ -16,5 +15,5 @@ import { convertLodashFp } from 'util/convert'
* @since 0.3.0
* @flow
*/
-const fill = convertLodashFp(_fill)
+const fill = convertArrayMethod('fill')
export { fill }
diff --git a/packages/immutadot/src/array/reverse.js b/packages/immutadot/src/array/reverse.js
index 08e0e814..f1388165 100644
--- a/packages/immutadot/src/array/reverse.js
+++ b/packages/immutadot/src/array/reverse.js
@@ -1,5 +1,4 @@
-import _reverse from 'lodash/fp/reverse'
-import { convertLodashFp } from 'util/convert'
+import { convertArrayMethod } from './convertArrayMethod'
/**
* Replaces an array reversing the elements from the former array.
@@ -13,5 +12,5 @@ import { convertLodashFp } from 'util/convert'
* @since 0.3.0
* @flow
*/
-const reverse = convertLodashFp(_reverse)
+const reverse = convertArrayMethod('reverse')
export { reverse }
diff --git a/packages/immutadot/src/array/slice.js b/packages/immutadot/src/array/slice.js
index 70525fe7..b69229c6 100644
--- a/packages/immutadot/src/array/slice.js
+++ b/packages/immutadot/src/array/slice.js
@@ -1,5 +1,4 @@
-import _slice from 'lodash/slice'
-import { convert } from 'core/convert'
+import { convertArrayMethod } from './convertArrayMethod'
/**
* Replaces an array by a slice of the former array from start
up to, but not including, end
.
@@ -15,5 +14,5 @@ import { convert } from 'core/convert'
* @since 0.3.0
* @flow
*/
-const slice = convert(_slice)
+const slice = convertArrayMethod('slice', false, true)
export { slice }
diff --git a/packages/immutadot/src/core/get.js b/packages/immutadot/src/core/get.js
new file mode 100644
index 00000000..e9a10f8b
--- /dev/null
+++ b/packages/immutadot/src/core/get.js
@@ -0,0 +1,23 @@
+import { isNil } from 'util/lang'
+import { unsafeToPath } from './toPath'
+
+/**
+* Gets the value at path
of obj
.
+* @memberof core
+* @param {*} obj The object.
+* @param {string|Array} path The path of the property to get.
+* @param {*} defaultValue The default value.
+* @return {*} Returns the value or defaultValue
.
+* @example get({ nested: { prop: 'val' } }, 'nested.prop') // => 'val'
+* @example get({ nested: { prop: 'val' } }, 'nested.unknown', 'default') // => 'default'
+* @since 1.0.0
+ */
+export function get(obj, path, defaultValue) {
+ function walkPath(curObj, remPath) {
+ if (remPath.length === 0) return curObj === undefined ? defaultValue : curObj
+ if (isNil(curObj)) return defaultValue
+ const [prop, ...pathRest] = remPath
+ return walkPath(curObj[prop], pathRest)
+ }
+ return walkPath(obj, unsafeToPath(path))
+}
diff --git a/packages/immutadot/src/core/get.spec.js b/packages/immutadot/src/core/get.spec.js
new file mode 100644
index 00000000..06585aa3
--- /dev/null
+++ b/packages/immutadot/src/core/get.spec.js
@@ -0,0 +1,28 @@
+/* eslint-env jest */
+import { get } from 'core'
+
+describe('Get', () => {
+ const obj = {
+ nested1: { prop: 'val' },
+ nested2: { arr: [{ val: 'arrVal' }] },
+ }
+
+ it('should get a prop', () => {
+ expect(get(obj, 'nested1.prop')).toBe('val')
+ expect(get(obj, 'nested1.prop.length')).toBe(3)
+ expect(get(obj, 'nested2.arr.length')).toBe(1)
+ expect(get(obj, 'nested2.arr[0].val')).toBe('arrVal')
+ })
+
+ it('should return undefined for unexisting path', () => {
+ expect(get(obj, 'nested1.foo')).toBe(undefined)
+ expect(get(obj, 'nested3.val')).toBe(undefined)
+ expect(get(obj, 'nested2.arr[1].val')).toBe(undefined)
+ })
+
+ it('should return defaultValue for unexisting path', () => {
+ expect(get(obj, 'nested1.foo', 'defaultValue')).toBe('defaultValue')
+ expect(get(obj, 'nested3.val', 'defaultValue')).toBe('defaultValue')
+ expect(get(obj, 'nested2.arr[1].val', 'defaultValue')).toBe('defaultValue')
+ })
+})
diff --git a/packages/immutadot/src/core/index.js b/packages/immutadot/src/core/index.js
index f2280550..090aec99 100644
--- a/packages/immutadot/src/core/index.js
+++ b/packages/immutadot/src/core/index.js
@@ -1,18 +1,12 @@
-import { convert } from './convert'
-import { set } from './set'
-import { toPath } from './toPath'
-import { unset } from './unset'
-import { update } from './update'
-
/**
- * Core functions.
- * @namespace core
- * @since 1.0.0
- */
-export {
- convert,
- set,
- toPath,
- unset,
- update,
-}
+* Core functions.
+* @namespace core
+* @since 1.0.0
+*/
+
+export { convert } from './convert'
+export { get } from './get'
+export { set } from './set'
+export { toPath } from './toPath'
+export { unset } from './unset'
+export { update } from './update'
diff --git a/packages/immutadot/src/core/set.js b/packages/immutadot/src/core/set.js
index 3ce140e8..328c39f7 100644
--- a/packages/immutadot/src/core/set.js
+++ b/packages/immutadot/src/core/set.js
@@ -3,7 +3,7 @@ import { apply } from './apply'
const setOperation = (obj, prop, _, value) => { obj[prop] = value }
/**
- * Sets the value at path
of object
.
+ * Sets the value at path
of obj
.
* @function
* @memberof core
* @param {*} obj The object to modify.
diff --git a/packages/immutadot/src/core/toPath.js b/packages/immutadot/src/core/toPath.js
index 3982789b..51bc7120 100644
--- a/packages/immutadot/src/core/toPath.js
+++ b/packages/immutadot/src/core/toPath.js
@@ -6,6 +6,7 @@ import {
} from './parser.utils'
import {
+ isNil,
isSymbol,
toString,
} from 'util/lang'
@@ -91,8 +92,7 @@ const isSliceIndexString = arg => isSliceIndex(arg ? Number(arg) : undefined)
*/
const allowingArrays = fn => arg => {
if (Array.isArray(arg)) return arg.map(toKey)
-
- return fn(toString(arg))
+ return fn(arg)
}
const emptyStringParser = str => str.length === 0 ? [] : null
@@ -139,16 +139,7 @@ const pathSegmentEndedByBracketParser = map(
([beforeBracket, atBracket]) => [beforeBracket, ...stringToPath(atBracket)],
)
-/**
- * Converts str
to a path represented as an array of keys.
- * @function
- * @param {string} str The string to convert
- * @return {Array} The path represented as an array of keys
- * @memberof core
- * @private
- * @since 1.0.0
- */
-const stringToPath = race([
+const applyParsers = race([
emptyStringParser,
quotedBracketNotationParser,
incompleteQuotedBracketNotationParser,
@@ -160,6 +151,20 @@ const stringToPath = race([
str => [str],
])
+/**
+ * Converts arg
to a path represented as an array of keys.
+ * @function
+ * @param {*} arg The value to convert
+ * @return {Array} The path represented as an array of keys
+ * @memberof core
+ * @private
+ * @since 1.0.0
+ */
+const stringToPath = arg => {
+ if (isNil(arg)) return []
+ return applyParsers(toString(arg))
+}
+
const MAX_CACHE_SIZE = 1000
const cache = new Map()
diff --git a/packages/immutadot/src/core/toPath.spec.js b/packages/immutadot/src/core/toPath.spec.js
index ed61edac..7813a01f 100644
--- a/packages/immutadot/src/core/toPath.spec.js
+++ b/packages/immutadot/src/core/toPath.spec.js
@@ -62,4 +62,9 @@ describe('ToPath', () => {
'1,2',
])
})
+
+ it('should give empty path for nil values', () => {
+ expect(toPath(null)).toEqual([])
+ expect(toPath(undefined)).toEqual([])
+ })
})
diff --git a/packages/immutadot/src/math/add.js b/packages/immutadot/src/math/add.js
index d4829ce8..65f4ddae 100644
--- a/packages/immutadot/src/math/add.js
+++ b/packages/immutadot/src/math/add.js
@@ -1,4 +1,3 @@
-import _add from 'lodash/add'
import { convert } from 'core/convert'
/**
@@ -14,5 +13,5 @@ import { convert } from 'core/convert'
* @since 0.1.7
* @flow
*/
-const add = convert(_add)
+const add = convert((value, addition) => value + addition)
export { add }
diff --git a/packages/immutadot/src/math/divide.js b/packages/immutadot/src/math/divide.js
index 42ed8606..7cc624f1 100644
--- a/packages/immutadot/src/math/divide.js
+++ b/packages/immutadot/src/math/divide.js
@@ -1,4 +1,3 @@
-import _divide from 'lodash/divide'
import { convert } from 'core/convert'
/**
@@ -14,5 +13,5 @@ import { convert } from 'core/convert'
* @since 0.3.0
* @flow
*/
-const divide = convert(_divide)
+const divide = convert((value, divider) => value / divider)
export { divide }
diff --git a/packages/immutadot/src/math/multiply.js b/packages/immutadot/src/math/multiply.js
index 7e8c16c8..00c33f25 100644
--- a/packages/immutadot/src/math/multiply.js
+++ b/packages/immutadot/src/math/multiply.js
@@ -1,4 +1,3 @@
-import _multiply from 'lodash/multiply'
import { convert } from 'core/convert'
/**
@@ -14,5 +13,5 @@ import { convert } from 'core/convert'
* @since 0.3.0
* @flow
*/
-const multiply = convert(_multiply)
+const multiply = convert((value, multiplier) => value * multiplier)
export { multiply }
diff --git a/packages/immutadot/src/math/subtract.js b/packages/immutadot/src/math/subtract.js
index 3af47921..5d6b9c56 100644
--- a/packages/immutadot/src/math/subtract.js
+++ b/packages/immutadot/src/math/subtract.js
@@ -1,4 +1,3 @@
-import _subtract from 'lodash/subtract'
import { convert } from 'core/convert'
/**
@@ -14,5 +13,5 @@ import { convert } from 'core/convert'
* @since 0.3.0
* @flow
*/
-const subtract = convert(_subtract)
+const subtract = convert((value, subtraction) => value - subtraction)
export { subtract }
diff --git a/packages/immutadot/src/object/assign.js b/packages/immutadot/src/object/assign.js
index c967789f..67fb502d 100644
--- a/packages/immutadot/src/object/assign.js
+++ b/packages/immutadot/src/object/assign.js
@@ -1,5 +1,4 @@
-import _assign from 'lodash/fp/assign'
-import { convertLodashFp } from 'util/convert'
+import { convert } from 'core/convert'
/**
* Replaces by an object assigning own enumerable string keyed properties of source objects to the destination object.
@@ -15,5 +14,5 @@ import { convertLodashFp } from 'util/convert'
* @since 0.1.12
* @flow
*/
-const assign = convertLodashFp(_assign)
+const assign = convert((obj, ...args) => Object.assign({ ...obj }, ...args))
export { assign }
diff --git a/packages/immutadot/src/seq/ChainWrapper.js b/packages/immutadot/src/seq/ChainWrapper.js
index bd27e5e3..db5315e0 100644
--- a/packages/immutadot/src/seq/ChainWrapper.js
+++ b/packages/immutadot/src/seq/ChainWrapper.js
@@ -5,11 +5,7 @@ import * as math from 'math'
import * as object from 'object'
import * as string from 'string'
-import concat from 'lodash/concat'
-import flow from 'lodash/flow'
-import mapValues from 'lodash/mapValues'
-import omit from 'lodash/omit'
-import toPath from 'lodash/toPath'
+import { unsafeToPath } from 'core/toPath'
/**
* Wrapper allowing to make sequences of immutadot functions calls on an object.
@@ -45,7 +41,7 @@ class ChainWrapper {
* @since 0.1.11
*/
_absolutePath(path) {
- return concat(toPath(this._path), toPath(path))
+ return unsafeToPath(this._path).concat(unsafeToPath(path))
}
/**
@@ -60,7 +56,7 @@ class ChainWrapper {
return new ChainWrapper(
this._wrapped,
this._path,
- concat(this._flow, object => fn(object, this._absolutePath(path), ...args)),
+ [...this._flow, object => fn(object, this._absolutePath(path), ...args)],
)
}
@@ -74,7 +70,7 @@ class ChainWrapper {
if (this._commited === null) {
this._commited = new ChainWrapper(
- flow(this._flow)(this._wrapped),
+ this._flow.reduce((obj, fn) => fn(obj), this._wrapped),
this._path,
)
}
@@ -122,21 +118,23 @@ class ChainWrapper {
*/
// Add namespaces functions to the ChainWrapper prototype
-[
+const { convert, toPath, ...filteredCore } = core // eslint-disable-line no-unused-vars
+const { set, unset, update, ...filteredObject } = object // eslint-disable-line no-unused-vars
+const namespaces = [
array,
- omit(core, ['convert', 'toPath']),
+ filteredCore,
lang,
math,
- omit(object, ['set', 'unset', 'update']),
+ filteredObject,
string,
-].forEach(namespace => Object.assign(
- ChainWrapper.prototype,
- mapValues(
- namespace,
- fn => function(path, ...args) {
- return this._call(fn, path, args) // eslint-disable-line no-invalid-this
- },
- ),
-))
+]
+namespaces.forEach(namespace => {
+ for (const fnName in namespace) {
+ const fn = namespace[fnName]
+ ChainWrapper.prototype[fnName] = function(path, ...args) {
+ return this._call(fn, path, args)
+ }
+ }
+})
export { ChainWrapper }
diff --git a/packages/immutadot/src/string/replace.js b/packages/immutadot/src/string/replace.js
index 49372f86..704e1554 100644
--- a/packages/immutadot/src/string/replace.js
+++ b/packages/immutadot/src/string/replace.js
@@ -1,4 +1,3 @@
-import _replace from 'lodash/replace'
import { convert } from 'core/convert'
/**
@@ -15,5 +14,5 @@ import { convert } from 'core/convert'
* @since 0.3.0
* @flow
*/
-const replace = convert(_replace)
+const replace = convert((str, ...args) => str.replace(...args))
export { replace }
diff --git a/packages/immutadot/src/util/UsingWrapper.js b/packages/immutadot/src/util/UsingWrapper.js
index a8831373..6b8e39ba 100644
--- a/packages/immutadot/src/util/UsingWrapper.js
+++ b/packages/immutadot/src/util/UsingWrapper.js
@@ -5,14 +5,11 @@ import * as math from 'math'
import * as object from 'object'
import * as string from 'string'
-import concat from 'lodash/concat'
-import drop from 'lodash/drop'
-import get from 'lodash/get'
-import head from 'lodash/head'
-import isSymbol from 'lodash/isSymbol'
-import map from 'lodash/map'
-import mapValues from 'lodash/mapValues'
-import omit from 'lodash/omit'
+import { isSymbol } from 'util/lang'
+
+const { get } = core
+
+const head = arr => arr[0]
/**
* Wrapper allowing to specify one or several paths to use as arguments for an immutadot function call.
@@ -52,37 +49,36 @@ class UsingWrapper {
*/
_call(fn, object, path, pArgs) {
let callArgs = pArgs
- const args = concat(
- map(this._paths, usingPath => {
- if (isSymbol(usingPath)) {
- const arg = head(callArgs)
- callArgs = drop(callArgs)
- return arg
- }
- return get(object, usingPath)
- }),
- callArgs,
- )
+ const args = this._paths.map(usingPath => {
+ if (isSymbol(usingPath)) {
+ const arg = head(callArgs)
+ callArgs = callArgs.slice(1)
+ return arg
+ }
+ return get(object, usingPath)
+ }).concat(callArgs)
return fn(object, path, ...args)
}
}
// Add namespaces functions to the UsingWrapper prototype
-[
+const { convert, unset, toPath, ...filteredCore } = core // eslint-disable-line no-unused-vars
+const { get: _get, set, unset: _unset, update, ...filteredObject } = object // eslint-disable-line no-unused-vars
+const namespaces = [
array,
- omit(core, ['convert', 'unset', 'toPath']),
+ filteredCore,
lang,
math,
- omit(object, ['set', 'unset', 'update']),
+ filteredObject,
string,
-].forEach(namespace => Object.assign(
- UsingWrapper.prototype,
- mapValues(
- namespace,
- fn => function(object, path, ...args) {
- return this._call(fn, object, path, args) // eslint-disable-line no-invalid-this
- },
- ),
-))
+]
+namespaces.forEach(namespace => {
+ for (const fnName in namespace) {
+ const fn = namespace[fnName]
+ UsingWrapper.prototype[fnName] = function(object, path, ...args) {
+ return this._call(fn, object, path, args)
+ }
+ }
+})
export { UsingWrapper }
diff --git a/packages/immutadot/src/util/index.js b/packages/immutadot/src/util/index.js
index 45fddf40..d0089cfb 100644
--- a/packages/immutadot/src/util/index.js
+++ b/packages/immutadot/src/util/index.js
@@ -1,4 +1,3 @@
-import { convert } from './convert'
import { protect } from './protect'
import { using } from './using'
@@ -8,7 +7,6 @@ import { using } from './using'
* @since 0.1.13
*/
export {
- convert,
using,
protect,
}
diff --git a/packages/immutadot/src/util/lang.js b/packages/immutadot/src/util/lang.js
index 77ea3ee5..2da24716 100644
--- a/packages/immutadot/src/util/lang.js
+++ b/packages/immutadot/src/util/lang.js
@@ -55,9 +55,20 @@ const length = arg => {
*/
const toString = arg => typeof arg === 'string' ? arg : `${arg}`
+/**
+ * Tests whether arg
is a object.
+ * @param {*} arg The value to test
+ * @return {boolean} True if arg
is an Object
, false otherwise
+ * @memberof util
+ * @private
+ * @since 1.0.0
+ */
+const isObject = arg => arg instanceof Object
+
export {
isNaturalInteger,
isNil,
+ isObject,
isSymbol,
length,
toString,
diff --git a/packages/immutadot/src/util/lang.spec.js b/packages/immutadot/src/util/lang.spec.js
index ceb8ae9b..7d027ae0 100644
--- a/packages/immutadot/src/util/lang.spec.js
+++ b/packages/immutadot/src/util/lang.spec.js
@@ -2,6 +2,7 @@
import {
isNaturalInteger,
isNil,
+ isObject,
isSymbol,
length,
toString,
@@ -87,4 +88,35 @@ describe('Lang utils', () => {
expect(toString(666)).toBe('666')
})
})
+
+ describe('isObject', () => {
+ it('should return true for object', () => {
+ expect(isObject({})).toBe(true)
+ })
+
+ it('should return true for array', () => {
+ expect(isObject([])).toBe(true)
+ })
+
+ it('should return true for function', () => {
+ const func = () => 1
+ expect(isObject(func)).toBe(true)
+ })
+
+ it('should return true for string', () => {
+ expect(isObject('')).toBe(false)
+ })
+
+ it('should return true for number', () => {
+ expect(isObject(1)).toBe(false)
+ })
+
+ it('should return true for instance of wrappers', () => {
+ /* eslint-disable no-new-wrappers */
+ expect(isObject(new Number(1))).toBe(true)
+ expect(isObject(new String(''))).toBe(true)
+ expect(isObject(new Boolean(true))).toBe(true)
+ /* eslint-enable no-new-wrappers */
+ })
+ })
})
diff --git a/packages/immutadot/src/util/protect.js b/packages/immutadot/src/util/protect.js
index 62bad0d8..f85f6de6 100644
--- a/packages/immutadot/src/util/protect.js
+++ b/packages/immutadot/src/util/protect.js
@@ -1,8 +1,5 @@
import { chain } from 'seq/chain'
-import concat from 'lodash/concat'
-import get from 'lodash/get'
-import isEmpty from 'lodash/isEmpty'
-import isObject from 'lodash/isObject'
+import { isObject } from 'util/lang'
/**
* Proxy handler to protect object from mutations.
@@ -34,7 +31,7 @@ class ProtectHandler {
get(target, property) {
const reference = this._peek()[property]
if (!isObject(reference)) return reference
- return new Proxy(reference, new ProtectHandler(this.chainWrapperRef, concat(this.path, property)))
+ return new Proxy(reference, new ProtectHandler(this.chainWrapperRef, [...this.path, property]))
}
/**
@@ -46,7 +43,7 @@ class ProtectHandler {
* @since 0.3.0
*/
set(target, property, value) {
- this.chainWrapperRef.chainWrapper = this.chainWrapperRef.chainWrapper.set(concat(this.path, property), value)
+ this.chainWrapperRef.chainWrapper = this.chainWrapperRef.chainWrapper.set([...this.path, property], value)
return true
}
@@ -58,7 +55,7 @@ class ProtectHandler {
* @since 0.3.0
*/
deleteProperty(target, property) {
- this.chainWrapperRef.chainWrapper = this.chainWrapperRef.chainWrapper.unset(concat(this.path, property))
+ this.chainWrapperRef.chainWrapper = this.chainWrapperRef.chainWrapper.unset([...this.path, property])
return true
}
@@ -70,7 +67,7 @@ class ProtectHandler {
_peek() {
let peeked
this.chainWrapperRef.chainWrapper = this.chainWrapperRef.chainWrapper.peek(_peeked => { peeked = _peeked })
- return isEmpty(this.path) ? peeked : get(peeked, this.path)
+ return !this.path.length ? peeked : peeked[this.path]
}
}