{"id":16889959,"url":"https://github.com/t-mullen/logoot-crdt","last_synced_at":"2026-03-07T23:02:03.033Z","repository":{"id":120696325,"uuid":"150314367","full_name":"t-mullen/logoot-crdt","owner":"t-mullen","description":"Optimized Logoot CRDT implementation.","archived":false,"fork":false,"pushed_at":"2022-06-01T19:03:13.000Z","size":40,"stargazers_count":39,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-14T05:39:17.754Z","etag":null,"topics":["collaboration","crdt","real-time"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/t-mullen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"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},"funding":{"github":"t-mullen","patreon":"tmullen"}},"created_at":"2018-09-25T18:53:03.000Z","updated_at":"2024-10-24T03:04:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"4e808ec8-015a-4a02-81f2-6f1f2c152810","html_url":"https://github.com/t-mullen/logoot-crdt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/t-mullen/logoot-crdt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t-mullen%2Flogoot-crdt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t-mullen%2Flogoot-crdt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t-mullen%2Flogoot-crdt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t-mullen%2Flogoot-crdt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/t-mullen","download_url":"https://codeload.github.com/t-mullen/logoot-crdt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t-mullen%2Flogoot-crdt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30236045,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T19:01:10.287Z","status":"ssl_error","status_checked_at":"2026-03-07T18:59:58.103Z","response_time":53,"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":["collaboration","crdt","real-time"],"created_at":"2024-10-13T16:59:55.855Z","updated_at":"2026-03-07T23:02:03.016Z","avatar_url":"https://github.com/t-mullen.png","language":"JavaScript","funding_links":["https://github.com/sponsors/t-mullen","https://patreon.com/tmullen"],"categories":[],"sub_categories":[],"readme":"# logoot-crdt\nReplicate text or sequences over networks without conflicts.\n\nAllows an unlimited number of authors to seamlessly collaborate on text. Has much better memory performance than [woot-crdt](https://github.com/t-mullen/woot-crdt). \n\nUses an optimized version of the Logoot CRDT algorithm: https://hal.inria.fr/inria-00432368/document\n\nAlso adds some improvements:\n- An execution readiness check for deletions.\n- LSEQ base doubling to reduce identifier integer size.\n- A hybrid of the LSEQ random and boundary allocation strategys that should work for most editing behaviours.\n- Support for a 2-step initial state transfer.\n- Implemented as a tree for fast character position lookups.\n\nTODO:\n- Implement the Split optimization.\n- Implement some way of preventing Logoot's interleaving anomaly.\n- Performance benchmarks between different strategys.\n\n## example\n```javascript\nvar l1 = new Logoot('site1')\nvar l2 = new Logoot('site1')\n\n// send sync messages between peers\nl1.on('operation', (op) =\u003e {\n  // send through your network (just need at-least-once, in-order delivery)\n  l2.receive(op)\n})\nl2.on('operation', (op) =\u003e {\n  l1.receive(op)\n})\n\n// make concurrent changes\nl1.insert('abc', 0)\nl2.insert('123', 0)\n\n// the values eventually converge!\nl1.value() // 'abc123'\nl2.value() // 'abc123'\n```\n\n## install\n```html\n\u003cscript src=\"dist/logoot.js\u003e\"\u003e\u003c/script\u003e\n```\nor\n```\nnpm install --save logoot-crdt\n```\n\n## api\n### `var doc = new Logoot(site, [state], [bias])`\nCreate a new synchronized sequence.\n\n- `site` is a globally unique identifer.\n- `state` allows you to initialize from an existing sequence state. \n- `bias` is the bias for the probability distribution used to allocate identifiers. It defaults to `15`, which is a good value for most left-to-right editing usecases. If your sequence is randomly edited, use `1`.\n\n### `doc.insert(value, index)`\nInsert a new string.\n- `value` is the string value to insert.\n- `index` is the position to insert.\n\n### `doc.delete(index, [length])`\nDelete characters.\n- `index` starting position of deletion.\n- `length` number of characters to delete (default is `1`).\n\n### `doc.replaceRange(value, index, length)`\nReplace a range of elements with a new string.\n- `value` is the string value to insert.\n- `index` is the position to insert/delete.\n- `length` number of characters to delete before inserting (default is `0`).\n\n### `doc.setValue(value)`\nReplaces all text with the given value.\n- `value` is the string value to set the text to.\n\n### `doc.getState()`\nReturns the current state of the CRDT. Can be passed into the constructor of another sequence to transfer state or into `setState()`.\n\n### `doc.setState(state)`\nSets the current state of the CRDT. Equivalent to constructing a new instance with the given state.\n\nChanging the state is unsafe; edits may have been made while you are transfering state that will need to be integrated. The best way to handle this is a two-step sync:\n\n```javascript\nvar state = l1.getState()\nvar missedOperations = []\nnetwork.on('operation', (op) =\u003e {\n  l1.receive(op)\n  missedOperations.push(op) // save this to send to l2 later\n})\n\n// send state to l2 (l2 is not receiving any operations until now)\nl2.setState(state)\nnetwork.on('operation', op =\u003e { // l2 can now receive operations\n  l2.receive(op)\n})\n\n// then send all the operations l2 missed during sync (don't worry about duplicates)\nmissedOperations.forEach(op =\u003e l2.receive(op))\n\n// both peers are now safely synced\n```\n\n### `doc.on('operation', (op) =\u003e {})`\nThis event fires when an operation object needs to be sent to all other synchronized sequences.\n\n### `doc.receive(op)`\nReceive an operation object from another sequence.\n\n### `doc.value()`\nGet the full string content of the sequence. Useful for initializing the view.\n\n### `doc.on('insert', (event) =\u003e {})`\nThis event fires when a remote insertion has been integrated. Useful for updating the view. Event object looks like:\n\n```javascript\n{\n  value: 'a', // The character inserted\n  index: 0  // The index in the sequence\n}\n```\n\n### `doc.on('delete', (event) =\u003e {})`\nThis event fires when a remote insertion has been integrated. Useful for updating the view. Event object looks like:\n\n```javascript\n{\n  value: 'a', // The character deleted\n  index: 0  // The index in the sequence where the element was\n}\n```\n\n\n## Sponsors\nSupport this project by becoming a sponsor. Your logo will appear here with a link to your website. [[Become a sponsor](https://github.com/sponsors/t-mullen)]\n\n\u003ca href=\"https://filefire.ca\"\u003e\u003cimg src=\"https://user-images.githubusercontent.com/14932492/84754967-15413300-af8f-11ea-80b8-3d04cccc2671.png\" align=\"left\" height=\"48\" \u003e\u003c/a\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft-mullen%2Flogoot-crdt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ft-mullen%2Flogoot-crdt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft-mullen%2Flogoot-crdt/lists"}