Skip to content

Commit 1bdb45a

Browse files
authored
Merge pull request #1190 from dballance/master
Add lookaside to `traverse` - Limits DFS revisit
2 parents 66cff03 + 87f30b3 commit 1bdb45a

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

src/specmap/index.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class SpecMap {
8383
// We might consider making this (traversing & application) configurable later.
8484
function createKeyBasedPlugin(pluginObj) {
8585
return function* (patches, specmap) {
86+
const traversedRefs = {}
87+
8688
for (const patch of patches.filter(lib.isAdditiveMutation)) {
8789
yield* traverse(patch.value, patch.path, patch)
8890
}
@@ -102,9 +104,21 @@ class SpecMap {
102104
for (const key of Object.keys(obj)) {
103105
const val = obj[key]
104106
const updatedPath = path.concat(key)
105-
106-
if (lib.isObject(val)) {
107-
yield* traverse(val, updatedPath, patch)
107+
const isObj = lib.isObject(val)
108+
109+
// If the object has a meta '$$ref' - and store this $$ref
110+
// in a lookaside to prevent future traversals of this $ref's tree.
111+
const objRef = obj.$$ref
112+
const traversed = specmap.allowMetaPatches && traversedRefs[obj.$$ref]
113+
114+
if (!traversed) {
115+
if (isObj) {
116+
// Only store the ref if it exists
117+
if (specmap.allowMetaPatches && objRef) {
118+
traversedRefs[objRef] = true
119+
}
120+
yield* traverse(val, updatedPath, patch)
121+
}
108122
}
109123

110124
if (!isRootProperties && key === pluginObj.key) {

0 commit comments

Comments
 (0)