{"id":36438904,"url":"https://github.com/lukasbuenger/immutable-treeutils","last_synced_at":"2026-01-11T20:53:52.919Z","repository":{"id":52164389,"uuid":"43137421","full_name":"lukasbuenger/immutable-treeutils","owner":"lukasbuenger","description":"Functional tree traversal helpers for ImmutableJS data structures","archived":false,"fork":false,"pushed_at":"2023-01-03T20:44:24.000Z","size":578,"stargazers_count":77,"open_issues_count":7,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-11-22T20:22:41.688Z","etag":null,"topics":["immutablejs","javascript","tree"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lukasbuenger.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-25T11:52:12.000Z","updated_at":"2025-07-01T04:00:47.000Z","dependencies_parsed_at":"2023-02-01T10:01:24.202Z","dependency_job_id":null,"html_url":"https://github.com/lukasbuenger/immutable-treeutils","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/lukasbuenger/immutable-treeutils","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasbuenger%2Fimmutable-treeutils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasbuenger%2Fimmutable-treeutils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasbuenger%2Fimmutable-treeutils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasbuenger%2Fimmutable-treeutils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukasbuenger","download_url":"https://codeload.github.com/lukasbuenger/immutable-treeutils/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasbuenger%2Fimmutable-treeutils/sbom","scorecard":{"id":603963,"data":{"date":"2025-08-11","repo":{"name":"github.com/lukasbuenger/immutable-treeutils","commit":"c8ed22edc47e83697a2d1ac2eeb60d5f70facb8a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":2,"reason":"Found 2/8 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"57 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-pp7h-53gx-mx7r","Warn: Project is vulnerable to: GHSA-832h-xg76-4gv6","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-9vvw-cc9w-f27h","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-4gmj-3p3h-gm8h","Warn: Project is vulnerable to: GHSA-qrmc-fj45-qfc2","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-xf7w-r453-m56c","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-44pw-h2cw-w3vq","Warn: Project is vulnerable to: GHSA-jp4x-w63m-7wgm","Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-4hpf-3wq7-5rpr","Warn: Project is vulnerable to: GHSA-f522-ffg8-j8r6","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-282f-qqgm-c34q","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w9mr-4mfr-499f","Warn: Project is vulnerable to: GHSA-ph34-pc88-72gc","Warn: Project is vulnerable to: GHSA-m6cx-g6qm-p2cx","Warn: Project is vulnerable to: GHSA-x8qc-rrcw-4r46","Warn: Project is vulnerable to: GHSA-4328-8hgf-7wjr","Warn: Project is vulnerable to: GHSA-93f3-23rq-pjfp","Warn: Project is vulnerable to: GHSA-pw54-mh39-w3hc","Warn: Project is vulnerable to: GHSA-xgh6-85xh-479p","Warn: Project is vulnerable to: GHSA-gqgv-6jq5-jjj9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-2m39-62fm-q8r3","Warn: Project is vulnerable to: GHSA-mf6x-7mm4-x2g7","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-g7q5-pjjr-gqvp","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-xc7v-wxcw-j472"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T01:09:38.567Z","repository_id":52164389,"created_at":"2025-08-21T01:09:38.567Z","updated_at":"2025-08-21T01:09:38.567Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28323591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T18:42:50.174Z","status":"ssl_error","status_checked_at":"2026-01-11T18:39:13.842Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["immutablejs","javascript","tree"],"created_at":"2026-01-11T20:53:52.272Z","updated_at":"2026-01-11T20:53:52.913Z","avatar_url":"https://github.com/lukasbuenger.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Immutable TreeUtils\n===================\n\n1.2.0 | ![Travis status](https://travis-ci.org/lukasbuenger/immutable-treeutils.svg?branch=v1.2.0)\n\nThis CommonJS module is a collection of helpers to access and traverse [ImmutableJS](http://facebook.github.io/immutable-js/) tree data structure with a DOM-inspired interface.\n\nIt imposes some very basic conventions on your data structure, but I tried to make everything as low-level and configurable as possible. Still, a few\nconditions that need to be met remain:\n\n* A tree can have only one root node.\n* Every node has to provide a unique identifier value under a key that is the same for all nodes in the tree.\n* Child nodes have to be stored in an [List](http://facebook.github.io/immutable-js/docs/#/List) under a key that is the same for all nodes containing children.\n\nSupports and tested against ImmutableJS versions `^4.0.0-rc.9 || \u003e=3.8`.\nCheck the [changelog](https://github.com/lukasbuenger/immutable-treeutils/blob/v1.2.0/CHANGELOG.md) for further information and migration instructions.\n\n## Getting started\n\nYou probably should feel comfortable working with [ImmutableJS](http://facebook.github.io/immutable-js/) data structures, so if you don't I strongly recommend you to get familiar with the concepts of [ImmutableJS](http://facebook.github.io/immutable-js/) first.\n\n### Understanding key paths\n\nAs you already know, with [ImmutableJS](http://facebook.github.io/immutable-js/) we retrieve nested values like this:\n\n```js\nlet map = Immutable.Map({a: { b: 'c' }});\nmap.getIn(['a', 'b']);\n// 'c'\n```\nWe could say that the key path to the value `'c'` is `['a', 'b']`.\nInstead of an array you can also use [Seq](http://facebook.github.io/immutable-js/docs/#/Seq) objects to describe key paths:\n```js\nmap.getIn(Immutable.Seq(['a', 'b']));\n// 'c'\n```\n\nThis might feel a little over the top at first but comes with a few advantages that are pivotal to [TreeUtils](#TreeUtils).\nAs a matter of fact, all the functions in this lib, that give you a node or a collection of nodes don't return the actual [ImmutableJS](http://facebook.github.io/immutable-js/) values but the key paths to the substate where the resulting node(s) are located. A lot of operations become very trivial with key paths. Let's look at the [parent](#TreeUtils-parent) function. Determining the parent of a given node represented by a key path is as simple as this:\n```js\nlet nodePath = Immutable.Seq(['data', 'childNodes', 0, 'childNodes', 1]);\nlet parentPath = nodePath.skipLast(2);\n```\n\nThe actual retrieval of the [ImmutableJS](http://facebook.github.io/immutable-js/) values is left to you, but you will notice that working with key paths can be quite fun. Imagine you want to get value at key `content` of the next sibling of a given node. You could do this like so:\n```js\nlet keyPath = treeUtils.nextSibling(state, 'node-id');\nlet content = state.getIn(keyPath.concat('content'));\n\n// or even shorter\nlet content = state.getIn(treeUtils.nextSibling(state, 'node-id').concat('name'));\n```\n\n**Please note, that while ImmutableJS works well with Arrays as key paths, [TreeUtils](#TreeUtils) will only accept [Seq](http://facebook.github.io/immutable-js/docs/#/Seq) objects as valid key paths.**\n\n### Working with cursors\n\n[TreeUtils](#TreeUtils) works just fine with cursor libraries like [immutable-cursor](https://github.com/redbadger/immutable-cursor) because cursors actually implement [ImmutableJS](http://facebook.github.io/immutable-js/) interfaces.\n\n### Tree mutation\n\n[TreeUtils](#TreeUtils) doesn't provide mutation helpers, because IMHO the variety of use cases and implementations is just too huge to spec a sensible API for that kind of thing. However, simple mutation functions can easily be implemented. An insert function could look something like this:\n```js\nfunction insert(state, newNode, parentId, index) {\n\treturn state.updateIn(\n\t\ttree.getById(state, parentId).concat('childNodes'),\n\t\tchildNodes =\u003e childNodes.splice(index, 0, newNode)\n\t);\n}\n```\n\n### Install and setup\n\nInstall the package from [npm](https://www.npmjs.com/package/immutable-treeutils):\n\n```\nnpm install immutable-treeutils\n```\n\nImport the module and provide some state. Examples in the docs below refer to this data structure:\n\n```javascript\nconst Immutable = require('immutable');\n// import Immutable from 'immutable';\nconst TreeUtils = require('immutable-treeutils');\n// import TreeUtils from 'immutable-treeutils';\n\nlet treeUtils = new TreeUtils();\n\nlet data = Immutable.fromJS({\n\tid: 'root',\n\tname: 'My Documents',\n\ttype: 'folder',\n\tchildNodes: [\n\t\t{\n\t\t\tid: 'node-1',\n\t\t\tname: 'Pictures',\n\t\t\ttype: 'folder',\n\t\t\tchildNodes: [\n\t\t\t\t{\n\t\t\t\t\tid: 'node-2',\n\t\t\t\t\tname: 'Me in Paris',\n\t\t\t\t\ttype: 'image'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'node-3',\n\t\t\t\t\tname: 'Barbecue July 2015',\n\t\t\t\t\ttype: 'image'\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\tid: 'node-4',\n\t\t\tname: 'Music',\n\t\t\ttype: 'folder',\n\t\t\tchildNodes: [\n\t\t\t\t{\n\t\t\t\t\tid: 'node-5',\n\t\t\t\t\tname: 'Pink Floyd - Wish You Were Here',\n\t\t\t\t\ttype: 'audio'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'node-6',\n\t\t\t\t\tname: 'The Doors - People Are Strange',\n\t\t\t\t\ttype: 'audio'\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n});\n```\n\n## API Docs\n\n- - -\n\u003csub\u003e[See Source](https://github.com/lukasbuenger/immutable-treeutils/tree/v1.2.0/index.js)\u003c/sub\u003e\n- - - \n\u003ca id=\"TreeUtils\"\u003e\u003c/a\u003e\n\n\n\n\n### *class* TreeUtils\n\nA collection of functional tree traversal helper functions for [ImmutableJS](http://facebook.github.io/immutable-js/) data structures.\n\n**Example**\n\n```js\nvar treeUtils = new TreeUtils(Immutable.Seq(['path', 'to', 'tree']));\n```\n\n**With custom key accessors**\n\n```js\nvar treeUtils = new TreeUtils(Immutable.Seq(['path', 'to', 'tree']), '__id', '__children');\n```\n\n**With custom *no result*-default**\n\n```js\nvar treeUtils = new TreeUtils(Immutable.Seq(['path', 'to', 'tree']), 'id', 'children', false);\n```\n\n**Note**\nThe first argument of every method of a `TreeUtils` object is the state you want to analyse. I won't mention / explain it again in method descriptions bellow. The argument `idOrKeyPath` also appears in most signatures, its purpose is thoroughly explained in the docs of [byArbitrary](#TreeUtils-byArbitrary).\n\n\n###### Signature:\n```js\nnew TreeUtils(\n   rootPath?: immutable.Seq,\n   idKey?: string,\n   childNodesKey?: string,\n   nonValue?: any\n)\n```\n\n###### Arguments:\n* `rootPath` - The path to the substate of your [ImmutableJS](http://facebook.github.io/immutable-js/) state that represents the root node of your tree. Default: `Immutable.Seq()`.\n* `idKey` - The name of the key that points at unique identifiers of all nodes in your tree . Default: `'id'`.\n* `childNodesKey` - The name of the key at which child nodes can be found. Default: `'childNodes'`.\n* `noneValue` - The value that will get returned if a query doesn't return any results. Default: `undefined`.\n\n###### Returns:\n* A new `TreeUtils` object\n \n\n- - - \n\u003ca id=\"TreeUtils-walk\"\u003e\u003c/a\u003e\n\n\n\n#### *method* walk()\n\nMain traversal algorithm. Lets you walk over all nodes in the tree **in no particular order**.\n\n###### Signature:\n```js\nwalk(\n   state: Immutable.Iterable,\n   iterator: (\n     accumulator: any,\n     keyPath: Immutable.Seq\u003cstring|number\u003e\n     stop: (\n       value: any\n     ): any\n   ): any,\n   path?: Immutable.Seq\u003cstring|number\u003e\n): any\n```\n\n###### Arguments:\n* `iterator` - A function that gets passed an accumulator, the current key path and a stop function:\n   * If the iterator returns a value, this value will be kept as reduction and passed as accumulator to further iterations.\n   * If the iterator returns a `stop` call, the walk operation will return immediately, giving back any value you passed to the `stop` function.\n* `path` - The key path that points at the root of the (sub)tree you want to walk over. Default: The `TreeUtils` object's `rootPath`.\n\n###### Returns:\nThe result of the walk operation.\n \n\n- - - \n\u003ca id=\"TreeUtils-nodes\"\u003e\u003c/a\u003e\n\n\n\n#### *method* nodes()\n\n```js\ntreeUtils.nodes(state).forEach(\n  keyPath =\u003e\n    console.log(treeUtils.id(state, keyPath));\n)\n```\n\n###### Signature:\n```\nnodes(\n    state: Immutable.Iterable,\n    path?: Immutable.Seq\u003cstring|number\u003e\n): Immutable.List\u003cImmutable.Seq\u003cstring|number\u003e\u003e\n```\n\n###### Arguments:\n* `path` - The key path that points at the root of the (sub)tree whose descendants you want to iterate. Default: The `TreeUtils` object's `rootPath`.\n\n###### Returns:\nAn **unordered** [List](http://facebook.github.io/immutable-js/docs/#/List) of all key paths that point to nodes in the tree, including the root of the (sub)tree..\n \n\n- - - \n\u003ca id=\"TreeUtils-find\"\u003e\u003c/a\u003e\n\n\n\n#### *method* find()\n\nReturns the key path to the first node for which `compatator` returns `true`. Uses [nodes](#TreeUtils-nodes) internally and as [nodes](#TreeUtils-nodes) is an **unordered** List, you should probably use this to find unique occurences of data.\n```js\ntreeUtils.find(state, node =\u003e node.get('name') === 'Me in Paris');\n// Seq [\"childNodes\", 0, \"childNodes\", 0]\n```\n\n###### Signature:\n```js\nfind(\n   state: Immutable.Iterable,\n   comparator: (\n        node: Immutable.Iterable,\n        keyPath: Immutable.Seq\u003cstring|number\u003e\n    ): boolean,\n   path?: Immutable.Seq\u003cstring|number\u003e\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Arguments:\n* `comparator` - A function that gets passed a `node` and its `keyPath` and should return whether it fits the criteria or not.\n* `path?` - An optional key path to the (sub)state you want to analyse: Default: The `TreeUtils` object's `rootPath`.\n\n###### Returns:\nThe key path to the first node for which `comparator` returned `true`.\n \n\n- - - \n\u003ca id=\"TreeUtils-filter\"\u003e\u003c/a\u003e\n\n\n\n#### *method* filter()\n\nReturns an [List](http://facebook.github.io/immutable-js/docs/#/List) of key paths pointing at the nodes for which `comparator` returned `true`.\n```js\ntreeUtils.filter(state, node =\u003e node.get('type') === 'folder');\n//List [ Seq[], Seq[\"childNodes\", 0], Seq[\"childNodes\", 1] ]\n```\n\n###### Signature:\n```js\nfilter(\n    state: Immutable.Iterable,\n    comparator: (\n        node: Immutable.Iterable,\n        keyPath: Immutable.Seq\u003cstring|number\u003e\n    ): boolean,\n    path?: Immutable.Seq\u003cstring|number\u003e\n): List\u003cImmutable.Seq\u003cstring|number\u003e\u003e\n```\n\n###### Arguments:\n* `comparator` - A function that gets passed a `node` and its `keyPath` and should return whether it fits the criteria or not.\n* `path?` - An optional key path to the (sub)state you want to analyse: Default: The `TreeUtils` object's `rootPath`.\n\n\n###### Returns:\nA [List](http://facebook.github.io/immutable-js/docs/#/List) of all the key paths that point at nodes for which `comparator` returned `true`.\n \n\n- - - \n\u003ca id=\"TreeUtils-byId\"\u003e\u003c/a\u003e\n\n\n\n#### *method* byId()\n\nReturns the key path to the node with id === `id`.\n\n###### Signature:\n```js\nid(\n   state: Immutable.Iterable,\n   id: string\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Arguments:\n* `id` - A unique identifier\n\n###### Returns:\nThe key path to the node with id === `id`.\n \n\n- - - \n\u003ca id=\"TreeUtils-byArbitrary\"\u003e\u003c/a\u003e\n\n\n\n#### *method* byArbitrary()\n\nReturns `idOrKeyPath` if it is a [Seq](http://facebook.github.io/immutable-js/docs/#/Seq), else returns the result of [byId](#TreeUtils-byId) for `idOrKeyPath`. This is used in all other functions that work on a unique identifiers in order to reduce the number of lookup operations.\n\n###### Signature:\n```js\nbyArbitrary(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e\n): Immutable.Seq\u003cstring|number\u003e\n```\n###### Returns:\nThe key path pointing at the node found for id === `idOrKeyPath` or, if is a [Seq](http://facebook.github.io/immutable-js/docs/#/Seq), the `idOrKeyPath` itself.\n\n \n\n- - - \n\u003ca id=\"TreeUtils-id\"\u003e\u003c/a\u003e\n\n\n\n#### *method* id()\n\nReturns the id for the node at `keyPath`. Most useful when you want to get the id of the result of a previous tree query:\n```js\ntreeUtils.id(state, treeUtils.parent(state, 'node-3'));\n// 'node-1'\n```\n\n###### Signature:\n```js\nid(\n   state: Immutable.Iterable,\n   keyPath: Immutable.Seq\u003cstring|number\u003e\n): string\n```\n\n###### Arguments:\n* `keyPath` - The absolute key path to the substate / node whose id you want to retrieve\n\n###### Returns:\nThe unique identifier of the node at the given key path.\n\n \n\n- - - \n\u003ca id=\"TreeUtils-nextSibling\"\u003e\u003c/a\u003e\n\n\n\n#### *method* nextSibling()\n\n###### Signature:\n```js\nnextSibling(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the next sibling node of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-previousSibling\"\u003e\u003c/a\u003e\n\n\n\n#### *method* previousSibling()\n\n###### Signature:\n```js\npreviousSibling(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the previous sibling node of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-firstChild\"\u003e\u003c/a\u003e\n\n\n\n#### *method* firstChild()\n\n###### Signature:\n```js\nfirstChild(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the first child node of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-lastChild\"\u003e\u003c/a\u003e\n\n\n\n#### *method* lastChild()\n\n###### Signature:\n```js\nlastChild(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the last child node of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-siblings\"\u003e\u003c/a\u003e\n\n\n\n#### *method* siblings()\n\n###### Signature:\n```js\nsiblings(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e\n): Immutable.List\u003cImmutable.Seq\u003cstring|number\u003e\u003e\n```\n\n###### Returns:\nReturns a [List](http://facebook.github.io/immutable-js/docs/#/List) of key paths pointing at the sibling nodes of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-childNodes\"\u003e\u003c/a\u003e\n\n\n\n#### *method* childNodes()\n\n###### Signature:\n```js\nchildNodes(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e\n): Immutable.List\u003cImmutable.Seq\u003cstring|number\u003e\u003e\n```\n\n###### Returns:\nReturns a [List](http://facebook.github.io/immutable-js/docs/#/List) of all child nodes of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-childAt\"\u003e\u003c/a\u003e\n\n\n\n#### *method* childAt()\n\n###### Signature:\n```js\nchildAt(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n   index: number\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the child node at position of `index` of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-descendants\"\u003e\u003c/a\u003e\n\n\n\n#### *method* descendants()\n\n###### Signature:\n```js\ndescendants(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): Immutable.List\u003cImmutable.Seq\u003cstring|number\u003e\u003e\n```\n\n###### Returns:\nReturns a list of key paths pointing at all descendants of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-childIndex\"\u003e\u003c/a\u003e\n\n\n\n#### *method* childIndex()\n\n###### Signature:\n```js\nchildIndex(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): number\n```\n\n###### Returns:\nReturns the index at which the node at `idOrKeyPath` is positioned in its parent child nodes list.\n \n\n- - - \n\u003ca id=\"TreeUtils-hasChildNodes\"\u003e\u003c/a\u003e\n\n\n\n#### *method* hasChildNodes()\n\n###### Signature:\n```js\nhasChildNodes(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): boolean\n```\n\n###### Returns:\nReturns whether the node at `idOrKeyPath` has children.\n \n\n- - - \n\u003ca id=\"TreeUtils-numChildNodes\"\u003e\u003c/a\u003e\n\n\n\n#### *method* numChildNodes()\n\n###### Signature:\n```js\nnumChildNodes(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): number\n```\n\n###### Returns:\nReturns the number of child nodes the node at `idOrKeyPath` has.\n \n\n- - - \n\u003ca id=\"TreeUtils-parent\"\u003e\u003c/a\u003e\n\n\n\n#### *method* parent()\n\n###### Signature:\n```js\nparent(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the key path to the parent of the node at `idOrKeyPath`.\n \n\n- - - \n\u003ca id=\"TreeUtils-ancestors\"\u003e\u003c/a\u003e\n\n\n\n#### *method* ancestors()\n\n###### Signature:\n```js\nancestors(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nAn [List](http://facebook.github.io/immutable-js/docs/#/List) of all key paths that point at direct ancestors of the node at `idOrKeyPath`.\n \n\n- - - \n\u003ca id=\"TreeUtils-depth\"\u003e\u003c/a\u003e\n\n\n\n#### *method* depth()\n\n###### Signature:\n```js\ndepth(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): number\n```\n\n###### Returns:\nA numeric representation of the depth of the node at `idOrKeyPath`\n \n\n- - - \n\u003ca id=\"TreeUtils-position\"\u003e\u003c/a\u003e\n\n\n\n#### *method* position()\n\nThis method is a very naive attempt to calculate a unique numeric position descriptor that can be used to compare two nodes for their absolute position in the tree.\n```js\ntreeUtils.position(state, 'node-4') \u003e treeUtils.position(state, 'node-3');\n// true\n```\n\nPlease note that `position` should not get used to do any comparison with the root node.\n\n###### Signature:\n```js\nposition(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): number\n```\n\n###### Returns:\nReturns a unique numeric value that represents the absolute position of the node at `idOrKeyPath`.\n \n\n- - - \n\u003ca id=\"TreeUtils-right\"\u003e\u003c/a\u003e\n\n\n\n#### *method* right()\n\nReturns the key path to the next node to the right. The next right node is either:\n* The first child node.\n* The next sibling.\n* The next sibling of the first ancestor that in fact has a next sibling.\n* The none value\n\n```js\nvar nodePath = treeUtils.byId(state, 'root');\nwhile (nodePath) {\n   console.log(nodePath);\n   nodePath = treeUtils.right(state, nodePath);\n}\n// 'root'\n// 'node-1'\n// 'node-2'\n// 'node-3'\n// 'node-4'\n// 'node-5'\n// 'node-6'\n```\n\n###### Signature:\n```js\nright(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the key path to the node to the right of the one at `idOrKeyPath`.\n \n\n- - - \n\u003ca id=\"TreeUtils-left\"\u003e\u003c/a\u003e\n\n\n\n#### *method* left()\n\nReturns the key path to the next node to the left. The next left node is either:\n* The last descendant of the previous sibling node.\n* The previous sibling node.\n* The parent node.\n* The none value\n\n```js\nvar nodePath = treeUtils.lastDescendant(state, 'root');\nwhile (nodePath) {\n   console.log(nodePath);\n   nodePath = treeUtils.left(state, nodePath);\n}\n// 'node-6'\n// 'node-5'\n// 'node-4'\n// 'node-3'\n// 'node-2'\n// 'node-1'\n// 'root'\n```\n\n\n###### Signature:\n```js\nleft(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the key path to the node to the right of the one at `idOrKeyPath`.\n \n\n- - - \n\u003ca id=\"TreeUtils-firstDescendant\"\u003e\u003c/a\u003e\n\n\n\n#### *method* firstDescendant()\n\nAlias of [firstChild](#TreeUtils-firstChild).\n \n\n- - - \n\u003ca id=\"TreeUtils-lastDescendant\"\u003e\u003c/a\u003e\n\n\n\n#### *method* lastDescendant()\n\nReturns the key path to the most right node in the given subtree (keypath). The last child of the most deep descendant, if that makes any sense. Look at the example:\n\n```js\ntreeUtils.lastDescendant(state, 'root');\n// 'node-6'\n```\n\n###### Signature:\n```js\nlastDescendant(\n   state: Immutable.Iterable,\n   idOrKeyPath: string|Immutable.Seq\u003cstring|number\u003e,\n): Immutable.Seq\u003cstring|number\u003e\n```\n\n###### Returns:\nReturns the key path to the last descendant of the node at `idOrKeyPath`.\n \n\n\n\n## Development\n\nSetup:\n```\ngit clone https://github.com/lukasbuenger/immutable-treeutils\nnpm install\n```\n\nRun the tests:\n```\nnpm test\n```\n\nBuild the docs / README:\n```\nnpm run docs\n```\n\nUpdate all local dependencies:\n```\nnpx ncu -a\n```\n\nThere's a pre-commit hook in place that keeps things in line with the [Prettier](https://github.com/prettier/prettier) guidelines. Please note that Node \u003e= 4.2 is required for the pre-commit hooks ([lint-staged](https://github.com/okonet/lint-staged), [husky](https://github.com/typicode/husky))\n\n## Changelog\n\nSee [CHANGELOG](https://github.com/lukasbuenger/immutable-treeutils/blob/v1.2.0/CHANGELOG.md)\n\n## License\n\nSee [LICENSE](https://github.com/lukasbuenger/immutable-treeutils/blob/v1.2.0/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukasbuenger%2Fimmutable-treeutils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukasbuenger%2Fimmutable-treeutils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukasbuenger%2Fimmutable-treeutils/lists"}