Skip to content

Commit

Permalink
feat(traverse): visitor can return a leave callback
Browse files Browse the repository at this point in the history
  • Loading branch information
aleclarson committed Jul 3, 2024
1 parent 94bb8fe commit d3563ba
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/object/traverse.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isArray, isIterable, isPlainObject, last } from 'radashi'
import { isArray, isFunction, isIterable, isPlainObject, last } from 'radashi'

/**
* Iterate an object's properties and those of any nested objects.
Expand Down Expand Up @@ -66,14 +66,14 @@ export function traverse(
}

context.path.push(key)
if (
visitor(
(context.value = value),
(context.key = key),
context.parent,
context,
) === false
) {
const result = visitor(
(context.value = value),
(context.key = key),
context.parent,
context,
)

if (result === false) {
return (ok = false)
}

Expand All @@ -87,6 +87,10 @@ export function traverse(
!context.parents.includes(value)
) {
traverse(value)

if (isFunction(result)) {
result()
}
}

context.path.pop()
Expand Down Expand Up @@ -147,7 +151,7 @@ export type TraverseVisitor = (
key: keyof any,
parent: object,
context: TraverseContext,
) => boolean | void
) => (() => void) | boolean | void

/**
* The context object for the `traverse` function.
Expand Down
16 changes: 16 additions & 0 deletions tests/object/traverse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,20 @@ describe('traverse', () => {
expect(paths).toEqual([['a'], ['a', 'b']])
expect(parents).toEqual([[obj], [obj, obj.a]])
})

test('visitor can return a leave callback', () => {
const obj = { a: { b: 2 } }
const visited: [keyof any, unknown][] = []
_.traverse(obj, (value, key) => {
visited.push([key, value])
return () => {
visited.push([key, value])
}
})
expect(visited).toEqual([
['a', { b: 2 }],
['b', 2],
['a', { b: 2 }],
])
})
})

0 comments on commit d3563ba

Please sign in to comment.