Skip to content

Commit

Permalink
Merge pull request #77 from TehShrike/v2
Browse files Browse the repository at this point in the history
deepmerge 2: merge harder
  • Loading branch information
TehShrike committed Oct 9, 2017
2 parents 94a59c4 + d87eb96 commit 198f75c
Show file tree
Hide file tree
Showing 9 changed files with 649 additions and 673 deletions.
141 changes: 0 additions & 141 deletions README.markdown

This file was deleted.

8 changes: 8 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# [2.0.0](https://github.com/KyleAMathews/deepmerge/releases/tag/v2.0.0)

- breaking: the array merge algorithm has changed from a complicated thing to `target.concat(source).map(element => cloneUnlessOtherwiseSpecified(element, optionsArgument))`
- breaking: The `clone` option now defaults to `true`
- feature: `merge.all` now accepts an array of any size, even 0 or 1 elements

See [pull request 77](https://github.com/KyleAMathews/deepmerge/pull/77).

# [1.5.2](https://github.com/KyleAMathews/deepmerge/releases/tag/v1.5.2)

- fix: no longer attempts to merge React elements [#76](https://github.com/KyleAMathews/deepmerge/issues/76)
Expand Down
90 changes: 42 additions & 48 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,64 @@
var isMergeableObject = require('is-mergeable-object')

function emptyTarget(val) {
return Array.isArray(val) ? [] : {}
return Array.isArray(val) ? [] : {}
}

function cloneIfNecessary(value, optionsArgument) {
var clone = optionsArgument && optionsArgument.clone === true
return (clone && isMergeableObject(value)) ? deepmerge(emptyTarget(value), value, optionsArgument) : value
function cloneUnlessOtherwiseSpecified(value, optionsArgument) {
var clone = !optionsArgument || optionsArgument.clone !== false

return (clone && isMergeableObject(value))
? deepmerge(emptyTarget(value), value, optionsArgument)
: value
}

function defaultArrayMerge(target, source, optionsArgument) {
var destination = target.slice()
source.forEach(function(e, i) {
if (typeof destination[i] === 'undefined') {
destination[i] = cloneIfNecessary(e, optionsArgument)
} else if (isMergeableObject(e)) {
destination[i] = deepmerge(target[i], e, optionsArgument)
} else if (target.indexOf(e) === -1) {
destination.push(cloneIfNecessary(e, optionsArgument))
}
})
return destination
return target.concat(source).map(function(element) {
return cloneUnlessOtherwiseSpecified(element, optionsArgument)
})
}

function mergeObject(target, source, optionsArgument) {
var destination = {}
if (isMergeableObject(target)) {
Object.keys(target).forEach(function(key) {
destination[key] = cloneIfNecessary(target[key], optionsArgument)
})
}
Object.keys(source).forEach(function(key) {
if (!isMergeableObject(source[key]) || !target[key]) {
destination[key] = cloneIfNecessary(source[key], optionsArgument)
} else {
destination[key] = deepmerge(target[key], source[key], optionsArgument)
}
})
return destination
var destination = {}
if (isMergeableObject(target)) {
Object.keys(target).forEach(function(key) {
destination[key] = cloneUnlessOtherwiseSpecified(target[key], optionsArgument)
})
}
Object.keys(source).forEach(function(key) {
if (!isMergeableObject(source[key]) || !target[key]) {
destination[key] = cloneUnlessOtherwiseSpecified(source[key], optionsArgument)
} else {
destination[key] = deepmerge(target[key], source[key], optionsArgument)
}
})
return destination
}

function deepmerge(target, source, optionsArgument) {
var sourceIsArray = Array.isArray(source)
var targetIsArray = Array.isArray(target)
var options = optionsArgument || { arrayMerge: defaultArrayMerge }
var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray
var sourceIsArray = Array.isArray(source)
var targetIsArray = Array.isArray(target)
var options = optionsArgument || { arrayMerge: defaultArrayMerge }
var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray

if (!sourceAndTargetTypesMatch) {
return cloneIfNecessary(source, optionsArgument)
} else if (sourceIsArray) {
var arrayMerge = options.arrayMerge || defaultArrayMerge
return arrayMerge(target, source, optionsArgument)
} else {
return mergeObject(target, source, optionsArgument)
}
if (!sourceAndTargetTypesMatch) {
return cloneUnlessOtherwiseSpecified(source, optionsArgument)
} else if (sourceIsArray) {
var arrayMerge = options.arrayMerge || defaultArrayMerge
return arrayMerge(target, source, optionsArgument)
} else {
return mergeObject(target, source, optionsArgument)
}
}

deepmerge.all = function deepmergeAll(array, optionsArgument) {
if (!Array.isArray(array) || array.length < 2) {
throw new Error('first argument should be an array with at least two elements')
}
if (!Array.isArray(array)) {
throw new Error('first argument should be an array')
}

// we are sure there are at least 2 values, so it is safe to have no initial value
return array.reduce(function(prev, next) {
return deepmerge(prev, next, optionsArgument)
})
return array.reduce(function(prev, next) {
return deepmerge(prev, next, optionsArgument)
}, {})
}

module.exports = deepmerge
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
},
"main": "dist/umd.js",
"module": "dist/es.js",
"browser": "dist/cjs.js",
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"build": "rollup -c",
"test": "npm run build && tap test/*.js && jsmd README.markdown"
"test": "npm run build && tap test/*.js && jsmd readme.md"
},
"devDependencies": {
"is-mergeable-object": "1.1.0",
Expand Down

0 comments on commit 198f75c

Please sign in to comment.