{"id":23147310,"url":"https://github.com/christianhg/diff-trees","last_synced_at":"2025-08-17T17:33:26.787Z","repository":{"id":74471148,"uuid":"316028404","full_name":"christianhg/diff-trees","owner":"christianhg","description":"For diffing ordered trees","archived":false,"fork":false,"pushed_at":"2022-11-09T21:21:24.000Z","size":1122,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-24T22:01:03.102Z","etag":null,"topics":["diff-trees"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/christianhg.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}},"created_at":"2020-11-25T18:55:14.000Z","updated_at":"2023-04-04T11:26:28.000Z","dependencies_parsed_at":"2023-04-25T07:46:50.040Z","dependency_job_id":null,"html_url":"https://github.com/christianhg/diff-trees","commit_stats":{"total_commits":78,"total_committers":2,"mean_commits":39.0,"dds":"0.17948717948717952","last_synced_commit":"2c2e2edda1879b2fa9a630c6c19526ff568f3cde"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhg%2Fdiff-trees","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhg%2Fdiff-trees/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhg%2Fdiff-trees/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhg%2Fdiff-trees/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christianhg","download_url":"https://codeload.github.com/christianhg/diff-trees/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230151950,"owners_count":18181318,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["diff-trees"],"created_at":"2024-12-17T16:52:05.070Z","updated_at":"2024-12-17T16:52:05.838Z","avatar_url":"https://github.com/christianhg.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# diff-trees\n\n\u003e For diffing ordered trees\n\n[![npm module](https://badge.fury.io/js/diff-trees.svg)](https://www.npmjs.org/package/diff-trees)\n\n![diff-trees](https://raw.githubusercontent.com/christianhg/diff-trees/main/diff-trees.png)\n\nA single `diffTrees` function is exported:\n\n```ts\ndeclare function diffTrees\u003cTValue\u003e(\n  treeA: TreeNode\u003c{ value: TValue }\u003e,\n  treeB: TreeNode\u003c{ value: TValue }\u003e\n): DiffTree\u003cTValue\u003e;\n```\n\nIt takes two trees of type `TreeNode`:\n\n```ts\ntype TreeNode\u003cTValues\u003e = {\n  id: string;\n  children: TreeNode\u003cTValues\u003e[];\n} \u0026 TValues;\n```\n\nAnd produces a single tree of type `DiffTree` which is an array containing one or two `DiffTreeNode`s. The second `DiffTreeNode` is included if the root of the tree was deleted.\n\n```ts\ntype DiffTree\u003cTValue\u003e =\n  | [DiffTreeNode\u003cTValue\u003e]\n  | [DiffTreeNode\u003cTValue\u003e, DiffTreeNode\u003cTValue\u003e];\n```\n\n```ts\ntype DiffTreeNode\u003cTValue\u003e = Omit\u003cTreeNode\u003c{ value: TValue }\u003e, 'children'\u003e \u0026 {\n  change: Change;\n  children: DiffTreeNode\u003cTValue\u003e[];\n};\n```\n\nWhere a `Change` is:\n\n```ts\ntype Change =\n  | [ChangeType.Unchanged]\n  | [ChangeType.Inserted]\n  | [ChangeType.Deleted]\n  | [ChangeType.Updated]\n  | [ChangeType.Moved]\n  | [ChangeType.Moved, ChangeType.Updated];\n```\n\n- `ChangeType.Unchanged` denotes unchanged nodes.\n- `ChangeType.Inserted` denotes new nodes.\n- `ChangeType.Deleted` denotes deleted nodes.\n- `ChangeType.Updated` denotes nodes where the `value` changed.\n- `ChangeType.Moved` denotes nodes that moved to another subtree or changed place within the same subtree.\n\n---\n\nThe `value` in a `TreeNode` can is generic. If the `value` has changed, the `DiffTreeNode` is annotated with `ChangeType.Updated`. By default, values are compared using [strict equality (`===`)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality). To change how values are compared, add a custom `valueEquality` function to the optional `options` object:\n\n```ts\ndeclare function diffTrees\u003cTValue\u003e(\n  treeA: TreeNode\u003c{ value: TValue }\u003e,\n  treeB: TreeNode\u003c{ value: TValue }\u003e,\n  options?: {\n    valueEquality: (a: TValue, b: TValue) =\u003e boolean;\n  }\n): DiffTreeNode\u003cTValue\u003e;\n```\n\n## Examples\n\n```ts\ndiffTrees(\n  { id: '1', value: 'a', children: [] },\n  { id: '1', value: 'a', children: [] }\n);\n\n// =\u003e\n\n[\n  {\n    id: '1',\n    value: 'a',\n    children: [],\n    change: [ChangeType.Unchanged],\n  },\n];\n```\n\n```ts\ndiffTrees(\n  { id: '1', value: 'a', children: [] },\n  { id: '2', value: 'b', children: [] }\n);\n\n// =\u003e\n\n[\n  {\n    id: '2',\n    value: 'b',\n    children: [],\n    change: [ChangeType.Inserted],\n  },\n  {\n    id: '1',\n    value: '1',\n    children: [],\n    change: [ChangeType.Deleted],\n  },\n];\n```\n\n```ts\ndiffTrees(\n  { id: '1', value: 'a', children: [] },\n  { id: '1', value: 'a', children: [{ id: '2', value: 'b', children: [] }] }\n);\n\n// =\u003e\n\n[\n  {\n    id: '1',\n    value: 'a',\n    change: [ChangeType.Unchanged],\n    children: [\n      { id: '2', value: 'b', change: [ChangeType.Inserted], children: [] },\n    ],\n  },\n];\n```\n\n```ts\ndiffTrees(\n  {\n    id: '1',\n    value: 'a',\n    children: [\n      { id: '2', value: 'b', children: [] },\n      { id: '3', value: 'c', children: [] },\n    ],\n  },\n  {\n    id: '1',\n    value: 'a',\n    children: [\n      { id: '3', value: 'c2', children: [] },\n      { id: '2', value: 'b', children: [] },\n    ],\n  }\n);\n\n// =\u003e\n\n[\n  {\n    id: '1',\n    value: 'a',\n    change: [ChangeType.Unchanged],\n    children: [\n      {\n        id: '3',\n        value: 'c2',\n        change: [ChangeType.Moved, ChangeType.Updated],\n        children: [],\n      },\n      {\n        id: '2',\n        value: 'b',\n        change: [ChangeType.Moved],\n        children: [],\n      },\n    ],\n  },\n];\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristianhg%2Fdiff-trees","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristianhg%2Fdiff-trees","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristianhg%2Fdiff-trees/lists"}