diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57a254ea..46664df7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## 0.0.16
+* `Versions`:
+ * `MicroUtils`: `0.17.5`
* `NavigationChain` got its own optional id
* `NavigationChain` and `NavigationNode` got `findChain` extension
* `NavigationChain` and `NavigationNode` got `findNode` extension
diff --git a/core/src/commonMain/kotlin/extensions/Chain.kt b/core/src/commonMain/kotlin/extensions/Chain.kt
index 11798fc8..53129564 100644
--- a/core/src/commonMain/kotlin/extensions/Chain.kt
+++ b/core/src/commonMain/kotlin/extensions/Chain.kt
@@ -40,27 +40,45 @@ fun NavigationChain.findChain(id: NavigationChainId): NavigationCha
// Drop/replace/push by node id
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropInSubTree]
+ */
fun NavigationChain.dropInSubTree(
id: NavigationNodeId
): Boolean = chainOrNodeEither().dropInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropNodeInSubTree]
+ */
fun NavigationChain.dropNodeInSubTree(id: String) = chainOrNodeEither().dropNodeInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[replaceInSubTree]
+ */
fun NavigationChain.replaceInSubTree(
id: NavigationNodeId,
config: Base,
): Boolean = chainOrNodeEither().replaceInSubTree(id, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[replaceInSubTree]
+ */
fun NavigationChain.replaceInSubTree(
id: String,
config: Base
) = chainOrNodeEither().replaceInSubTree(id, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTree]
+ */
fun NavigationChain.pushInSubTree(
inChainWith: NavigationNodeId,
config: Base
): Boolean = chainOrNodeEither().pushInSubTree(inChainWith, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTreeByNodeId]
+ */
fun NavigationChain.pushInSubTreeByNodeId(
inChainWithNodeId: String,
config: Base
@@ -68,19 +86,31 @@ fun NavigationChain.pushInSubTreeByNodeId(
// Drop/push by chain id
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropInSubTree]
+ */
fun NavigationChain.dropInSubTree(
id: NavigationChainId
) = chainOrNodeEither().dropInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropChainInSubTree]
+ */
fun NavigationChain.dropChainInSubTree(
id: String
) = chainOrNodeEither().dropChainInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTree]
+ */
fun NavigationChain.pushInSubTree(
inChainWithNodeId: NavigationChainId,
config: Base
) = chainOrNodeEither().pushInSubTree(inChainWithNodeId, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTreeByChainId]
+ */
fun NavigationChain.pushInSubTreeByChainId(
inChainWithNodeId: String,
config: Base
diff --git a/core/src/commonMain/kotlin/extensions/EitherChainOrNode.kt b/core/src/commonMain/kotlin/extensions/EitherChainOrNode.kt
index ec025547..e6963fa3 100644
--- a/core/src/commonMain/kotlin/extensions/EitherChainOrNode.kt
+++ b/core/src/commonMain/kotlin/extensions/EitherChainOrNode.kt
@@ -3,13 +3,17 @@ package dev.inmo.navigation.core.extensions
import dev.inmo.navigation.core.ChainOrNodeEither
import dev.inmo.navigation.core.NavigationChainId
import dev.inmo.navigation.core.NavigationNodeId
-import dev.inmo.navigation.core.visiter.walk
import dev.inmo.navigation.core.visiter.walkOnChains
import dev.inmo.navigation.core.visiter.walkOnNodes
// Drop/replace/push by chain id
+/**
+ * Will drop all nodes in tree with [dev.inmo.navigation.core.NavigationNode.id] == [id]
+ *
+ * **This method will start its work with [this] as a root**
+ */
fun ChainOrNodeEither.dropInSubTree(
id: NavigationNodeId
): Boolean {
@@ -22,8 +26,17 @@ fun ChainOrNodeEither.dropInSubTree(
return deleted
}
+/**
+ * Shortcut for [dropInSubTree]
+ */
fun ChainOrNodeEither.dropNodeInSubTree(id: String) = dropInSubTree(NavigationNodeId(id))
+/**
+ * Will [dev.inmo.navigation.core.NavigationChain.replace] all nodes in tree with
+ * [dev.inmo.navigation.core.NavigationNode.id] == [id] by a new one with [config]
+ *
+ * **This method will start its work with [this] as a root**
+ */
fun ChainOrNodeEither.replaceInSubTree(
id: NavigationNodeId,
config: Base,
@@ -35,24 +48,36 @@ fun ChainOrNodeEither.replaceInSubTree(
return replaced
}
+/**
+ * Shortcut for method [replaceInSubTree]
+ */
fun ChainOrNodeEither.replaceInSubTree(
id: String,
config: Base
) = replaceInSubTree(NavigationNodeId(id), config)
+/**
+ * Will push on top in all chains with any [dev.inmo.navigation.core.NavigationNode] in
+ * [dev.inmo.navigation.core.NavigationChain.stack] with [dev.inmo.navigation.core.NavigationNode.id] == [id]
+ *
+ * **This method will start its work with [this] as a root**
+ */
fun ChainOrNodeEither.pushInSubTree(
- inChainWith: NavigationNodeId,
+ id: NavigationNodeId,
config: Base
): Boolean {
var pushed = false
walkOnNodes {
- if (it.id == inChainWith) {
+ if (it.id == id) {
pushed = it.chain.push(config) != null || pushed
}
}
return pushed
}
+/**
+ * Shortcut for method [pushInSubTree]
+ */
fun ChainOrNodeEither.pushInSubTreeByNodeId(
inChainWithNodeId: String,
config: Base
@@ -60,6 +85,11 @@ fun ChainOrNodeEither.pushInSubTreeByNodeId(
// Drop/push by chain id
+/**
+ * Will drop all chains in tree with [dev.inmo.navigation.core.NavigationChain.id] == [id]
+ *
+ * **This method will start its work with [this] as a root**
+ */
fun ChainOrNodeEither.dropInSubTree(
id: NavigationChainId
): Boolean {
@@ -73,21 +103,32 @@ fun ChainOrNodeEither.dropInSubTree(
return deleted
}
+/**
+ * Shortcut for method [dropInSubTree]
+ */
fun ChainOrNodeEither.dropChainInSubTree(id: String) = dropInSubTree(NavigationChainId(id))
+/**
+ * Will push on top in all chains with [dev.inmo.navigation.core.NavigationChain.id] == [id]
+ *
+ * **This method will start its work with [this] as a root**
+ */
fun ChainOrNodeEither.pushInSubTree(
- inChainWith: NavigationChainId,
+ id: NavigationChainId,
config: Base
): Boolean {
var pushed = false
walkOnChains {
- if (it.id == inChainWith) {
+ if (it.id == id) {
pushed = it.push(config) != null || pushed
}
}
return pushed
}
+/**
+ * Shortcut for method [pushInSubTree]
+ */
fun ChainOrNodeEither.pushInSubTreeByChainId(
inChainWithNodeId: String,
config: Base
diff --git a/core/src/commonMain/kotlin/extensions/Node.kt b/core/src/commonMain/kotlin/extensions/Node.kt
index 9674b8e5..0a8ee226 100644
--- a/core/src/commonMain/kotlin/extensions/Node.kt
+++ b/core/src/commonMain/kotlin/extensions/Node.kt
@@ -40,27 +40,45 @@ fun NavigationNode<*, Base>.findChain(id: NavigationChainId): NavigationC
// Drop/replace/push by node id
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropInSubTree]
+ */
fun NavigationNode<*, Base>.dropInSubTree(
id: NavigationNodeId
): Boolean = chainOrNodeEither().dropInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropNodeInSubTree]
+ */
fun NavigationNode<*, Base>.dropNodeInSubTree(id: String) = chainOrNodeEither().dropNodeInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[replaceInSubTree]
+ */
fun NavigationNode<*, Base>.replaceInSubTree(
id: NavigationNodeId,
config: Base,
): Boolean = chainOrNodeEither().replaceInSubTree(id, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[replaceInSubTree]
+ */
fun NavigationNode<*, Base>.replaceInSubTree(
id: String,
config: Base
) = chainOrNodeEither().replaceInSubTree(id, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTree]
+ */
fun NavigationNode<*, Base>.pushInSubTree(
inChainWith: NavigationNodeId,
config: Base
): Boolean = chainOrNodeEither().pushInSubTree(inChainWith, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTreeByNodeId]
+ */
fun NavigationNode<*, Base>.pushInSubTreeByNodeId(
inChainWithNodeId: String,
config: Base
@@ -68,19 +86,31 @@ fun NavigationNode<*, Base>.pushInSubTreeByNodeId(
// Drop/push by chain id
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropInSubTree]
+ */
fun NavigationNode<*, Base>.dropInSubTree(
id: NavigationChainId
) = chainOrNodeEither().dropInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[dropChainInSubTree]
+ */
fun NavigationNode<*, Base>.dropChainInSubTree(
id: String
) = chainOrNodeEither().dropChainInSubTree(id)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTree]
+ */
fun NavigationNode<*, Base>.pushInSubTree(
inChainWithNodeId: NavigationChainId,
config: Base
) = chainOrNodeEither().pushInSubTree(inChainWithNodeId, config)
+/**
+ * Shortcut for method [dev.inmo.navigation.core.ChainOrNodeEither].[pushInSubTreeByChainId]
+ */
fun NavigationNode<*, Base>.pushInSubTreeByChainId(
inChainWithNodeId: String,
config: Base
diff --git a/core/src/commonMain/kotlin/visiter/NavigationTreeWalker.kt b/core/src/commonMain/kotlin/visiter/NavigationTreeWalker.kt
deleted file mode 100644
index ce53d681..00000000
--- a/core/src/commonMain/kotlin/visiter/NavigationTreeWalker.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-package dev.inmo.navigation.core.visiter
-
-import dev.inmo.micro_utils.common.Either
-import dev.inmo.micro_utils.common.either
-import dev.inmo.micro_utils.common.onFirst
-import dev.inmo.micro_utils.common.onSecond
-import dev.inmo.navigation.core.ChainOrNodeEither
-import dev.inmo.navigation.core.NavigationChain
-import dev.inmo.navigation.core.NavigationNode
-import dev.inmo.navigation.core.chainOrNodeEither
-import dev.inmo.navigation.core.onChain
-import dev.inmo.navigation.core.onNode
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flow
-
-/**
- * Will walk on whole tree of navigation. The order of walking next:
- *
- * * First faced [NavigationNode] will be passed to the [onNode] first
- * * First faced [NavigationChain] will be passed to the [onChain] first
- *
- * @receiver [Either] node or chain which assumed as a root for walking and will be used as first parameter for
- * calling of [onChain] or [onNode]
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun ChainOrNodeEither.walk(
- onNodeOrChain: NavigationNodeOrChainVisitingCallback
-) {
- val visitingQueue = ArrayDeque>()
- visitingQueue.add(this)
-
- while (visitingQueue.isNotEmpty()) {
- val firstOne = visitingQueue.removeFirst()
- onNodeOrChain(firstOne)
-
- firstOne.onFirst {
- visitingQueue.addAll(0, it.stackFlow.value.map { it.chainOrNodeEither() })
- }.onSecond {
- visitingQueue.addAll(0, it.subchainsFlow.value.map { it.chainOrNodeEither() })
- }
- }
-}
-
-/**
- * Will walk on whole tree of navigation. **This function will start since [this] [NavigationChain]**
- *
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun NavigationChain.walk(
- onNodeOrChain: NavigationNodeOrChainVisitingCallback
-) = chainOrNodeEither().walk(onNodeOrChain)
-
-/**
- * Will walk on whole tree of navigation. **This function will start since [this] [NavigationChain]**
- *
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun NavigationNode.walk(
- onNodeOrChain: NavigationNodeOrChainVisitingCallback
-) = chainOrNodeEither().walk(onNodeOrChain)
-
-/**
- * Will walk on whole tree of navigation. The order of walking next:
- *
- * * First faced [NavigationNode] will be passed to the [onNode] first
- * * First faced [NavigationChain] will be passed to the [onChain] first
- *
- * @receiver [Either] node or chain which assumed as a root for walking and will be used as first parameter for
- * calling of [onChain] or [onNode]
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun ChainOrNodeEither.walkOnChains(
- onChain: NavigationChainVisitingCallback
-) = walk { it.onChain(onChain) }
-
-/**
- * Will walk on whole tree of navigation. **This function will start since [this] [NavigationChain]**
- *
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun NavigationChain.walkOnChains(
- onChain: NavigationChainVisitingCallback
-) = chainOrNodeEither().walkOnChains(onChain)
-
-/**
- * Will walk on whole tree of navigation. **This function will start since [this] [NavigationChain]**
- *
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun NavigationNode.walkOnChains(
- onChain: NavigationChainVisitingCallback
-) = chainOrNodeEither().walkOnChains(onChain)
-
-/**
- * Will walk on whole tree of navigation. The order of walking next:
- *
- * * First faced [NavigationNode] will be passed to the [onNode] first
- * * First faced [NavigationChain] will be passed to the [onChain] first
- *
- * @receiver [Either] node or chain which assumed as a root for walking and will be used as first parameter for
- * calling of [onChain] or [onNode]
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun ChainOrNodeEither.walkOnNodes(
- onNode: NavigationNodeVisitingCallback
-) = walk { it.onNode(onNode) }
-
-/**
- * Will walk on whole tree of navigation. **This function will start since [this] [NavigationChain]**
- *
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun NavigationChain.walkOnNodes(
- onNode: NavigationNodeVisitingCallback
-) = chainOrNodeEither().walkOnNodes(onNode)
-
-/**
- * Will walk on whole tree of navigation. **This function will start since [this] [NavigationChain]**
- *
- * @param onNode Will be passed in call [NavigationNode.walk]
- * @param onChain Will be called for [this] [NavigationChain] and passed in [NavigationNode.walk]
- */
-inline fun NavigationNode.walkOnNodes(
- onNode: NavigationNodeVisitingCallback
-) = chainOrNodeEither().walkOnNodes(onNode)
-
-fun ChainOrNodeEither.walkFlow(): Flow> {
- return flow {
- walk { emit(it) }
- }
-}
-
-fun NavigationChain.walkFlow(): Flow> {
- return chainOrNodeEither().walkFlow()
-}
-
-fun NavigationNode.walkFlow(): Flow> {
- return chainOrNodeEither().walkFlow()
-}
diff --git a/core/src/commonMain/kotlin/visiter/Walk.kt b/core/src/commonMain/kotlin/visiter/Walk.kt
new file mode 100644
index 00000000..b70a863c
--- /dev/null
+++ b/core/src/commonMain/kotlin/visiter/Walk.kt
@@ -0,0 +1,57 @@
+package dev.inmo.navigation.core.visiter
+
+import dev.inmo.micro_utils.common.onFirst
+import dev.inmo.micro_utils.common.onSecond
+import dev.inmo.navigation.core.ChainOrNodeEither
+import dev.inmo.navigation.core.NavigationChain
+import dev.inmo.navigation.core.NavigationNode
+import dev.inmo.navigation.core.chainOrNodeEither
+
+
+/**
+ * Root fun for walking across the navigation tree starting with [this] as a root.
+ *
+ * **This function is not recursive**
+ *
+ * * Each met [NavigationNode] will be passed to [onNodeOrChain] and its [NavigationNode.subchains] will be added
+ * __in the beginning__ of visiting queue
+ * * Each met [NavigationChain] will be passed to [onNodeOrChain] and its [NavigationChain.stack] will be added
+ * __in the beginning__ of visiting queue
+ *
+ * None happen of the [onNodeOrChain] exceptions will be stopped.
+ *
+ * @see walkFlow
+ * @see walkOnChains
+ * @see walkOnNodes
+ */
+inline fun ChainOrNodeEither.walk(
+ onNodeOrChain: NavigationNodeOrChainVisitingCallback
+) {
+ val visitingQueue = ArrayDeque>()
+ visitingQueue.add(this)
+
+ while (visitingQueue.isNotEmpty()) {
+ val firstOne = visitingQueue.removeFirst()
+ onNodeOrChain(firstOne)
+
+ firstOne.onFirst {
+ visitingQueue.addAll(0, it.stackFlow.value.map { it.chainOrNodeEither() })
+ }.onSecond {
+ visitingQueue.addAll(0, it.subchainsFlow.value.map { it.chainOrNodeEither() })
+ }
+ }
+}
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walk]
+ */
+inline fun NavigationChain.walk(
+ onNodeOrChain: NavigationNodeOrChainVisitingCallback
+) = chainOrNodeEither().walk(onNodeOrChain)
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walk]
+ */
+inline fun NavigationNode.walk(
+ onNodeOrChain: NavigationNodeOrChainVisitingCallback
+) = chainOrNodeEither().walk(onNodeOrChain)
diff --git a/core/src/commonMain/kotlin/visiter/WalkFlow.kt b/core/src/commonMain/kotlin/visiter/WalkFlow.kt
new file mode 100644
index 00000000..8e80e675
--- /dev/null
+++ b/core/src/commonMain/kotlin/visiter/WalkFlow.kt
@@ -0,0 +1,33 @@
+package dev.inmo.navigation.core.visiter
+
+import dev.inmo.navigation.core.ChainOrNodeEither
+import dev.inmo.navigation.core.NavigationChain
+import dev.inmo.navigation.core.NavigationNode
+import dev.inmo.navigation.core.chainOrNodeEither
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
+
+
+/**
+ * Creates flow with visited [NavigationNode]s and [NavigationChain]s with [walk] throw whole tree using [this]
+ * as root
+ */
+fun ChainOrNodeEither.walkFlow(): Flow> {
+ return flow {
+ walk { emit(it) }
+ }
+}
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walkFlow]
+ */
+fun NavigationChain.walkFlow(): Flow> {
+ return chainOrNodeEither().walkFlow()
+}
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walkFlow]
+ */
+fun NavigationNode.walkFlow(): Flow> {
+ return chainOrNodeEither().walkFlow()
+}
diff --git a/core/src/commonMain/kotlin/visiter/WalkOnChains.kt b/core/src/commonMain/kotlin/visiter/WalkOnChains.kt
new file mode 100644
index 00000000..1fe300c9
--- /dev/null
+++ b/core/src/commonMain/kotlin/visiter/WalkOnChains.kt
@@ -0,0 +1,29 @@
+package dev.inmo.navigation.core.visiter
+
+import dev.inmo.navigation.core.ChainOrNodeEither
+import dev.inmo.navigation.core.NavigationChain
+import dev.inmo.navigation.core.NavigationNode
+import dev.inmo.navigation.core.chainOrNodeEither
+import dev.inmo.navigation.core.onChain
+
+/**
+ * Uses [walk] to visit whole navigation tree with [this] as root, but will pass in [onChain] lambda only visited
+ * [NavigationChain]s
+ */
+inline fun ChainOrNodeEither.walkOnChains(
+ onChain: NavigationChainVisitingCallback
+) = walk { it.onChain(onChain) }
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walkOnChains]
+ */
+inline fun NavigationChain.walkOnChains(
+ onChain: NavigationChainVisitingCallback
+) = chainOrNodeEither().walkOnChains(onChain)
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walkOnChains]
+ */
+inline fun NavigationNode.walkOnChains(
+ onChain: NavigationChainVisitingCallback
+) = chainOrNodeEither().walkOnChains(onChain)
diff --git a/core/src/commonMain/kotlin/visiter/WalkOnNodes.kt b/core/src/commonMain/kotlin/visiter/WalkOnNodes.kt
new file mode 100644
index 00000000..92fd6781
--- /dev/null
+++ b/core/src/commonMain/kotlin/visiter/WalkOnNodes.kt
@@ -0,0 +1,30 @@
+package dev.inmo.navigation.core.visiter
+
+import dev.inmo.navigation.core.ChainOrNodeEither
+import dev.inmo.navigation.core.NavigationChain
+import dev.inmo.navigation.core.NavigationNode
+import dev.inmo.navigation.core.chainOrNodeEither
+import dev.inmo.navigation.core.onNode
+
+
+/**
+ * Uses [walk] to visit whole navigation tree with [this] as root, but will pass in [onNode] lambda only visited
+ * [NavigationNode]s
+ */
+inline fun ChainOrNodeEither.walkOnNodes(
+ onNode: NavigationNodeVisitingCallback
+) = walk { it.onNode(onNode) }
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walkOnNodes]
+ */
+inline fun NavigationChain.walkOnNodes(
+ onNode: NavigationNodeVisitingCallback
+) = chainOrNodeEither().walkOnNodes(onNode)
+
+/**
+ * Shortcut for main [ChainOrNodeEither].[walkOnNodes]
+ */
+inline fun NavigationNode.walkOnNodes(
+ onNode: NavigationNodeVisitingCallback
+) = chainOrNodeEither().walkOnNodes(onNode)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index f582e83d..5953732e 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -5,7 +5,7 @@ kotlin-coroutines = "1.6.4"
kotlin-serialization = "1.5.0"
dokka = "1.8.10"
-microutils = "0.17.2"
+microutils = "0.17.5"
kslog = "1.0.0"
uuid = "0.7.0"