{"id":16642118,"url":"https://github.com/make-github-pseudonymous-again/js-search-tree-spec","last_synced_at":"2026-04-24T10:32:27.907Z","repository":{"id":75805168,"uuid":"307486320","full_name":"make-github-pseudonymous-again/js-search-tree-spec","owner":"make-github-pseudonymous-again","description":":mag: Search tree specification for JavaScript","archived":false,"fork":false,"pushed_at":"2021-04-26T14:09:27.000Z","size":2631,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-25T22:34:28.884Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://aureooms.github.io/js-search-tree-spec","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/make-github-pseudonymous-again.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-26T19:44:05.000Z","updated_at":"2021-12-20T23:41:05.000Z","dependencies_parsed_at":"2023-03-14T15:45:16.274Z","dependency_job_id":null,"html_url":"https://github.com/make-github-pseudonymous-again/js-search-tree-spec","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/make-github-pseudonymous-again/js-search-tree-spec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/make-github-pseudonymous-again%2Fjs-search-tree-spec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/make-github-pseudonymous-again%2Fjs-search-tree-spec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/make-github-pseudonymous-again%2Fjs-search-tree-spec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/make-github-pseudonymous-again%2Fjs-search-tree-spec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/make-github-pseudonymous-again","download_url":"https://codeload.github.com/make-github-pseudonymous-again/js-search-tree-spec/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/make-github-pseudonymous-again%2Fjs-search-tree-spec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32218958,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T10:26:35.452Z","status":"ssl_error","status_checked_at":"2026-04-24T10:25:27.643Z","response_time":64,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":[],"created_at":"2024-10-12T07:48:55.225Z","updated_at":"2026-04-24T10:32:27.881Z","avatar_url":"https://github.com/make-github-pseudonymous-again.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":":mag: [@aureooms/js-search-tree-spec](https://make-github-pseudonymous-again.github.io/js-search-tree-spec)\n==\n\nSearch tree specification for JavaScript.\nSee [docs](https://make-github-pseudonymous-again.github.io/js-search-tree-spec).\nParent is [@aureooms/js-bst](https://github.com/make-github-pseudonymous-again/js-bst).\n\n```js\n// eslint-disable-next-line ava/use-test\nimport ava from 'ava' ;\nimport * as spec from '@aureooms/js-search-tree-spec' ;\n\nspec.test(\n  ava ,\n  {\n    name: \"DummySearchTree\" , // Name for the implementation\n    empty: compare =\u003e new spec.DummySearchTree(compare) , // Return an empty search tree using `compare` to order keys\n    from: (compare, iterable) =\u003e spec.DummySearchTree.from(compare, iterable) , // Return a search tree using `compare` to order keys initialized with the values in iterable\n  } ,\n  {\n    length : true , // Do the implementations maintain a `length` property?\n    lengths : [0, 1, 16, 17, 31, 32, 33, 63, 64, 65] , // Tree sizes to test.\n  }\n) ;\n```\n\n[![License](https://img.shields.io/github/license/make-github-pseudonymous-again/js-search-tree-spec.svg)](https://raw.githubusercontent.com/make-github-pseudonymous-again/js-search-tree-spec/main/LICENSE)\n[![Version](https://img.shields.io/npm/v/@aureooms/js-search-tree-spec.svg)](https://www.npmjs.org/package/@aureooms/js-search-tree-spec)\n[![Build](https://img.shields.io/travis/make-github-pseudonymous-again/js-search-tree-spec/main.svg)](https://travis-ci.org/make-github-pseudonymous-again/js-search-tree-spec/branches)\n[![Dependencies](https://img.shields.io/david/make-github-pseudonymous-again/js-search-tree-spec.svg)](https://david-dm.org/make-github-pseudonymous-again/js-search-tree-spec)\n[![Dev dependencies](https://img.shields.io/david/dev/make-github-pseudonymous-again/js-search-tree-spec.svg)](https://david-dm.org/make-github-pseudonymous-again/js-search-tree-spec?type=dev)\n[![GitHub issues](https://img.shields.io/github/issues/make-github-pseudonymous-again/js-search-tree-spec.svg)](https://github.com/make-github-pseudonymous-again/js-search-tree-spec/issues)\n[![Downloads](https://img.shields.io/npm/dm/@aureooms/js-search-tree-spec.svg)](https://www.npmjs.org/package/@aureooms/js-search-tree-spec)\n\n[![Code issues](https://img.shields.io/codeclimate/issues/make-github-pseudonymous-again/js-search-tree-spec.svg)](https://codeclimate.com/github/make-github-pseudonymous-again/js-search-tree-spec/issues)\n[![Code maintainability](https://img.shields.io/codeclimate/maintainability/make-github-pseudonymous-again/js-search-tree-spec.svg)](https://codeclimate.com/github/make-github-pseudonymous-again/js-search-tree-spec/trends/churn)\n[![Code coverage (cov)](https://img.shields.io/codecov/c/gh/make-github-pseudonymous-again/js-search-tree-spec/main.svg)](https://codecov.io/gh/make-github-pseudonymous-again/js-search-tree-spec)\n[![Code technical debt](https://img.shields.io/codeclimate/tech-debt/make-github-pseudonymous-again/js-search-tree-spec.svg)](https://codeclimate.com/github/make-github-pseudonymous-again/js-search-tree-spec/trends/technical_debt)\n[![Documentation](https://make-github-pseudonymous-again.github.io/js-search-tree-spec//badge.svg)](https://make-github-pseudonymous-again.github.io/js-search-tree-spec//source.html)\n[![Package size](https://img.shields.io/bundlephobia/minzip/@aureooms/js-search-tree-spec)](https://bundlephobia.com/result?p=@aureooms/js-search-tree-spec)\n\n## :newspaper: Description\n\nThis package contains a specification test suite for search tree\nimplementations such as\n[@aureooms/js-red-black-tree](https://github.com/make-github-pseudonymous-again/js-red-black-tree),\n[@aureooms/js-splay-tree](https://github.com/make-github-pseudonymous-again/js-splay-tree),\nand\n[@aureooms/js-avl-tree](https://github.com/make-github-pseudonymous-again/js-avl-tree).\n\n## :woman_teacher: Specification\n\n### :balance_scale: Definition of a `Ternary Comparator`\n\nWe choose to parameterize trees using ternary comparator functions rather that\nkey functions (as is done in Python for instance).\n\n    Comparator = ( x , x ) -\u003e Number\n    Key = ( x ) -\u003e String\n\n    compare( a , b ) \u003c 0 \u003c=\u003e key( a ) \u003c key( b )\n    compare( a , b ) = 0 \u003c=\u003e key( a ) = key( b )\n    compare( a , b ) \u003e 0 \u003c=\u003e key( a ) \u003e key( b )\n\n#### Example of a `Ternary Comparator`\n\nThe following `Comparator` orders instances of `String`.\n\n```js\nconst compare = (a, b) =\u003e a \u003c b ? -1 : a \u003e b ? 1 : 0;\n```\n\n### Exposed tree constructors\n\nNo surprises here:\n\n```js\nconst { from , empty } = SearchTree ;\n```\n\n### `empty(Comparator) -\u003e SearchTree`\n\nCreate an empty search tree from a comparator function.\n\n```js\nlet tree = empty( compare ) ;\n```\n\n### `from(Comparator, Iterable) -\u003e Tree`\n\nCreate a search tree from a comparator function and an iterable.\n\n```js\nlet tree = from( compare , 'abc' ) ;\n```\n\n### `Tree#length -\u003e Number` (optional)\n\nReturns the number of elements in the tree.\n\n```js\nif ( tree.length \u003e 1 ) ...\n```\n\n### `Tree#isEmpty() -\u003e Boolean`\n\nReturns `true` if the tree is empty, `false` otherwise.\n\n```js\nreturn tree.isEmpty() ? 'empty' : 'not empty' ;\n```\n\n### `Tree#has(x) -\u003e Boolean`\n\nReturns `true` if the tree contains given element.\n\n```js\nif (tree.has(x)) ...\n```\n\n### Insertion\n\n#### `Tree#insert(x) -\u003e Reference`\n\nInsert given element in the tree and returns optional reference.\n\n```js\ntree.insert('abc');\n```\n\nCould also be called `Tree#add` instead.\n\n### Update\n\n#### `Tree#update(x) -\u003e Reference`\n\nUpdate given element in the tree and returns optional reference.\n\n```js\ntree.insert({key: 'abc', value: 0});\ntree.update({key: 'abc', value: 123});\n```\n\n### Removal\n\n#### `Tree#removeFirst(x) -\u003e Boolean`\n\nRemove first occurrence of element. Returns optional boolean indicating if an\nelement was removed.\n\n```js\ntree.insert('x');\ntree.insert('x');\ntree.removeFirst('x');\n```\n\n#### `Tree#removeLast(x) -\u003e Boolean`\n\nRemove last occurrence of element. Returns optional boolean indicating if an\nelement was removed.\n\n```js\ntree.insert('x');\ntree.insert('x');\ntree.removeLast('x');\n```\n\n#### `Tree#removeAll(x) -\u003e Boolean`\n\nRemove all occurrences of element. Returns optional boolean indicating if an\nelement was removed.\n\n```js\ntree.insert('x');\ntree.insert('x');\ntree.removeAll('x');\n```\n\n#### `Tree#remove(x) -\u003e Boolean`\n\nAlias for `Tree#removeFirst`.\n\n#### `Tree#delete(ref)`\n\nRemove element given reference.\n\n```js\nlet ref = tree.insert('abc');\ntree.delete(ref);\n```\n\nCould also be called `Tree#unlink` instead. Leaving `Tree#delete` as an alias\nfor `Tree#removeFirst` or `Tree#removeAll` to mimic the `Set` API.\n\n### Searching\n\n#### `Tree#find(x) -\u003e x`\n\n#### `Tree#predecessor(x) -\u003e x`\n\n#### `Tree#successor(x) -\u003e x`\n\n#### `Tree#leftMost() -\u003e x`\n\n#### `Tree#rightMost() -\u003e x`\n\n### Merging\n\n#### `Tree#meld(other)`\n\nMerge two trees. Merged trees are destroyed.\n\n```js\nlet a = from(compare, 'abc');\nlet b = from(compare, '123');\na.meld(b);\n```\n\n### Split\n\n#### `Tree#split(x) -\u003e [Tree, x, Tree]`\n\nSplit a tree at `x` such that\n\n```js\nconst [left, key, right] = tree.split(x);\nassert(compare(key, x) === 0);\nassert(isBinarySearchTree({key, left, right}));\n```\n\n### Visit\n\n#### `Tree#[Symbol.iterator]() -\u003e Iterator`\n\n#### `Tree#items() -\u003e Iterator`\n\nAlias for `Tree#[Symbol.iterator]()`.\n\n#### `Tree#reversed() -\u003e Iterator`\n\n#### `Tree#rangeIE(left, right) -\u003e Iterator`\n\n#### `Tree#rangeII(left, right) -\u003e Iterator`\n\n#### `Tree#rangeEI(left, right) -\u003e Iterator`\n\n#### `Tree#rangeEE(left, right) -\u003e Iterator`\n\n#### `Tree#range(left, right) -\u003e Iterator`\n\nAlias for `Tree#rangeIE(left, right) -\u003e Iterator`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmake-github-pseudonymous-again%2Fjs-search-tree-spec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmake-github-pseudonymous-again%2Fjs-search-tree-spec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmake-github-pseudonymous-again%2Fjs-search-tree-spec/lists"}