New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent mutable structures when merging Immutable objects using mergeDeep #1840
Changes from 10 commits
11952b6
8e06ea5
6a30077
8045f23
7591993
a68ea68
6ac0924
34ca015
ab51c3e
48183f1
3e9c703
050dfd0
e912a1b
cbaa071
25896fa
b526da3
63f4b80
1ab0cd9
31e46bd
6e3be74
5b43972
2bd33cb
be3e91f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -1,5 +1,9 @@ | ||||
import { isImmutable } from '../predicates/isImmutable'; | ||||
import { isIndexed } from '../predicates/isIndexed'; | ||||
import { isKeyed } from '../predicates/isKeyed'; | ||||
import { isSet } from '../predicates/isSet'; | ||||
import { IndexedCollection, KeyedCollection } from '../Collection'; | ||||
import { Seq } from '../Seq'; | ||||
import hasOwnProperty from '../utils/hasOwnProperty'; | ||||
import isDataStructure from '../utils/isDataStructure'; | ||||
import shallowCopy from '../utils/shallowCopy'; | ||||
|
@@ -68,11 +72,23 @@ export function mergeWithSources(collection, sources, merger) { | |||
|
||||
function deepMergerWith(merger) { | ||||
function deepMerger(oldValue, newValue, key) { | ||||
return isDataStructure(oldValue) && isDataStructure(newValue) | ||||
return isDataStructure(oldValue) && | ||||
isDataStructure(newValue) && | ||||
areMergeable(oldValue, newValue) | ||||
? mergeWithSources(oldValue, [newValue], deepMerger) | ||||
: merger | ||||
? merger(oldValue, newValue, key) | ||||
: newValue; | ||||
} | ||||
return deepMerger; | ||||
} | ||||
|
||||
function areMergeable(oldDataStructure, newDataStructure) { | ||||
const oldSeq = Seq(oldDataStructure); | ||||
const newSeq = Seq(newDataStructure); | ||||
return ( | ||||
isIndexed(oldSeq) === isIndexed(newSeq) && | ||||
isKeyed(oldSeq) === isKeyed(newSeq) && | ||||
isSet(oldSeq) === isSet(newSeq) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may need some test coverage to cover this, but I believe
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wondered about that, I should've looked into that more, makes sense. |
||||
); | ||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: it would still be nice to include a comment block above this function explaining why this implementation determines things are considered mergeable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Let me know if that's what you were thinking or if you were asking for a different explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this looks good to me. It's the connection between the collection categorization and this somewhat nuanced boolean logic that will be helpful when we look at this function again after our collective memory is lost