Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
436 commits
Select commit Hold shift + click to select a range
43815d8
fix lint error
synix Apr 25, 2024
8270373
Add Hocuspocus as a backend provider
fxsalazar Apr 25, 2024
927c236
Merge pull request #636 from fxsalazar/patch-1
dmonad Apr 25, 2024
387be70
make slice() function's doc more accurate
synix Apr 26, 2024
3df335c
update slice() function's doc
synix Apr 26, 2024
0af69cf
fix: markdownlint readme error
synix Apr 26, 2024
ce43124
[relative-positions] add option to configure whether to follow redon …
dmonad Apr 26, 2024
d56221b
Merge pull request #637 from synix/fix/readme-lint
dmonad Apr 26, 2024
91b718c
13.6.15
dmonad Apr 26, 2024
0511b66
Merge pull request #635 from synix/fix/unused-transaction
dmonad Apr 28, 2024
656b7e7
add more users
dmonad Apr 28, 2024
0896ed4
Merge branch 'main' into patch-1
dmonad Apr 28, 2024
13772bf
Merge pull request #603 from kevboh/patch-1
dmonad Apr 28, 2024
54594a2
Add y-op-sqlite to readme
malte-j Apr 30, 2024
06e71f6
Fix y-websocket server path
jasonbw May 9, 2024
cdd8e4f
Merge pull request #643 from jasonbw/patch-1
dmonad May 9, 2024
c264b1c
Merge pull request #640 from malte-j/patch-1
dmonad May 11, 2024
edad668
Update INTERNALS.md
i12345 May 15, 2024
72205a6
Merge pull request #644 from i12345/patch-1
dmonad May 15, 2024
d67a951
add y-postgresql info to readme
MaxNoetzold May 21, 2024
03593ae
fix linting errors
MaxNoetzold May 21, 2024
a4303f9
Merge pull request #646 from MaxNoetzold/patch-1
dmonad Jun 4, 2024
6932696
Export mergeDeleteSets
fuadsaud Jun 6, 2024
0973e0a
Merge pull request #648 from ellipsus-writes/export-merge-ds
dmonad Jun 7, 2024
0678ed1
fix event.path in observeDeep - closes #457
dmonad Jun 10, 2024
fbd088e
13.6.16
dmonad Jun 10, 2024
88506f6
Fixed star icon in README.md
szv Jun 11, 2024
2e79d03
Fixed markdown link for ellipsus.org in README.md
szv Jun 11, 2024
a47a48b
Merge pull request #649 from szv/readme-fixes
dmonad Jun 15, 2024
d4dac55
fix creating relative position from json when type name is the empty …
dmonad Jun 17, 2024
34b06b6
13.6.17
dmonad Jun 17, 2024
3f1746f
add lexical editor
dmonad Jun 17, 2024
2e5abad
fix #645 yjs/y-utility#8
dmonad Jun 18, 2024
1bfa6df
13.6.18
dmonad Jun 18, 2024
5e19c35
add react-yjs to bindings
nikgraf Jun 24, 2024
384ec4d
Merge pull request #651 from nikgraf/patch-2
dmonad Jun 30, 2024
f29cd2b
update users
dmonad Jul 10, 2024
c944a45
Add Y.Array.from() and yarray.clone() to API docs
mtreinik Jul 30, 2024
294c6a1
Remove erroneous ymap.get(index:number) from API docs
mtreinik Jul 30, 2024
56d5e32
Merge pull request #660 from mtreinik/main
dmonad Jul 30, 2024
eeb4c99
lint readme
dmonad Aug 5, 2024
dd17228
update markdownlint
dmonad Aug 6, 2024
44e5108
fix new lint issues
dmonad Aug 6, 2024
5b4d2a6
Add QDAcity to `README.md`
jul13579 Aug 29, 2024
3f9bfe4
Merge pull request #664 from jul13579/add-qdacity-to-readme
dmonad Aug 29, 2024
f2ff8b9
add kanbert as a user
dmonad Aug 30, 2024
95e2bc4
add secsync
dmonad Sep 2, 2024
7422b18
add eclipse theia as a user
dmonad Sep 3, 2024
c1ef9a1
add ScienHub as a user.
batchor Sep 5, 2024
4fb7789
add ScienHub as a user.
batchor Sep 5, 2024
f604250
add `ydoc.isDestroyed` property
dmonad Sep 10, 2024
9a993f8
13.6.19
dmonad Sep 10, 2024
9e9f294
Merge pull request #665 from batchor/main
dmonad Sep 19, 2024
8cd1a48
Y.Array.length should be 0 before it is integrated - #666
dmonad Sep 26, 2024
3bf44b9
#667 - add sanity messages when data is read before type is added to …
dmonad Oct 4, 2024
8152cf8
[#667] sanity checks for Yjs caveats. In dev_mode, objects inserted i…
dmonad Oct 4, 2024
4ff65b5
add devtools
dmonad Oct 7, 2024
345fd31
add yjs-inspector
dmonad Oct 7, 2024
487465d
lint
dmonad Oct 13, 2024
a304024
13.6.20
dmonad Oct 13, 2024
e804dd7
add y-crdt elexir bindings
dmonad Sep 4, 2024
cc2d732
add funding.json
dmonad Oct 19, 2024
42bbb44
fix errors in funding.json
dmonad Oct 19, 2024
6074f80
[funding.json] fix some validation issues
dmonad Oct 19, 2024
4f47355
add SuperViz Provider in yjs README
carlossantos74 Oct 22, 2024
2b7ea8a
Merge pull request #671 from carlossantos74/main
dmonad Oct 24, 2024
4329997
add stars to providers that sponsor yjs
dmonad Oct 24, 2024
8dc1296
update readme
dmonad Oct 24, 2024
4e2d3c8
docs: remove `@toeverything/y-indexeddb`
himself65 Nov 27, 2024
c951f2b
add Open Collaboration Tools as a user
dmonad Nov 28, 2024
0419b74
Merge pull request #676 from himself65/patch-1
dmonad Dec 4, 2024
4ffd370
Add PSPDFKit binding to README.md
hoangqwe159 Dec 5, 2024
d4d4ae5
Merge pull request #679 from hoangqwe159/main
dmonad Dec 14, 2024
4404d09
add nodejs specific tests
dmonad Dec 18, 2024
1b0f2e5
lint
dmonad Dec 18, 2024
f583d2a
fix #657 - relative positions issue when using followUndoneDeletions=…
dmonad Dec 20, 2024
89dddc2
13.6.21
dmonad Dec 20, 2024
f18eab2
Fix typos
szepeviktor Jan 3, 2025
1a0d4aa
Merge pull request #685 from szepeviktor/typos
dmonad Jan 7, 2025
e67b129
fix(yText): applyDelta should support both Delta and Ops[]
ykou-clickup Jan 9, 2025
3c9c0f1
Merge pull request #689 from ykou-clickup/patch-1
dmonad Jan 12, 2025
80e83a8
Revert "fix(yText): applyDelta should support both Delta and Ops[]"
dmonad Jan 12, 2025
2d2e662
Merge pull request #690 from yjs/revert-689-patch-1
dmonad Jan 12, 2025
bb5410b
marginally better typings for applyDelta - #689
dmonad Jan 12, 2025
1bec008
13.6.22
dmonad Jan 12, 2025
e53c44e
expose getItemCleanStart/End
dmonad Jan 15, 2025
c05b815
13.6.23
dmonad Jan 15, 2025
40725e3
Add Typst to Yjs users in README
reknih Jan 17, 2025
4b86576
Merge pull request #691 from reknih/add-typst
dmonad Jan 17, 2025
cc9a857
slightly optimize TreeWalker and integration process
dmonad Feb 24, 2025
69d4a5c
[UndoManager] support global undo
dmonad Mar 4, 2025
78e0527
13.6.24
dmonad Mar 4, 2025
09fbb62
improve documentation on global UndoManager
dmonad Mar 4, 2025
afa4c35
update titanic funding information - closes #696
dmonad Mar 5, 2025
e3739bc
test example for rejecting updates
dmonad Mar 5, 2025
35c030d
improve reject update example
dmonad Mar 6, 2025
3ecfb4e
add rowsncolumns
dmonad Mar 9, 2025
06cd5b5
README: Remove a duplicate SageMaker mention
hacklschorsch Mar 18, 2025
2ef9ccd
README: Remove duplicate btw mention
hacklschorsch Mar 18, 2025
ad0d915
Merge pull request #701 from hacklschorsch/patch-2
dmonad Mar 18, 2025
d5b5e7a
Update README.md to add https://github.com/kapv89/k_yrs_go to persist…
kapv89 Mar 25, 2025
34b9343
Merge pull request #702 from kapv89/patch-1
dmonad Mar 26, 2025
1b006dc
Update README.md
manstie Mar 31, 2025
0e31957
Merge pull request #703 from manstie/patch-2
dmonad Mar 31, 2025
66989ca
feat: add ace bindings
bajrangCoder Apr 1, 2025
a57f53e
Merge pull request #704 from bajrangCoder/ace-bindings
dmonad Apr 1, 2025
e17616c
Merge branch 'main' into patch-1
dmonad Apr 1, 2025
5200598
Merge pull request #700 from hacklschorsch/patch-1
dmonad Apr 1, 2025
f1f96e1
lint
dmonad Apr 1, 2025
2b621eb
add JupyterGIS
dmonad Apr 1, 2025
4d67167
add yrs-warp to providers
dmonad Apr 2, 2025
b9aa098
add y-op-sqlite
dmonad Apr 7, 2025
c2097e7
fix iterating through deleted structs when they dont exist
dmonad Apr 18, 2025
e866222
lint
dmonad Apr 18, 2025
0ae8d6c
13.6.25
dmonad Apr 18, 2025
13cd563
[iterateStructs] additional check for non-existent structs
dmonad Apr 18, 2025
2f4b8c3
13.6.26
dmonad Apr 18, 2025
2fbc73e
Update README.md
Yeshan-K Apr 22, 2025
120856d
Update README.md
Yeshan-K Apr 22, 2025
6b7e65d
Merge pull request #708 from Yeshan-K/main
dmonad Apr 22, 2025
5037831
add funding manifest to .well-known
dmonad Apr 27, 2025
780b27b
update funding manifest
dmonad Apr 27, 2025
29ab38c
add y-crdt
dmonad Apr 27, 2025
120d611
better description of myself
dmonad Apr 27, 2025
2f33d16
lint
dmonad Apr 27, 2025
bd645c4
remove y-crdt (separate funding.json is maintained in y-crdt org)
dmonad Apr 30, 2025
7dad24d
support bigints in Y.Map.set - fixes #711
dmonad May 13, 2025
987c9eb
13.6.27
dmonad May 13, 2025
4ea9a75
README: add pluv.io provider
i3dly May 26, 2025
2d09ed4
add electric-sql as a provider
dmonad May 27, 2025
273c53b
add yjs-cf-ws-provider
dmonad May 27, 2025
55df734
add lightpage as a user
dmonad Jun 10, 2025
7310314
Add reearth-flow to the README as a collaborative data calculation tool
kasugamirai Jun 7, 2025
bc941a5
README: Update y-sweet debugger hyperlink
cloneot Jun 15, 2025
2995fcd
Merge pull request #721 from cloneot/patch-1
dmonad Jun 16, 2025
fcfdba1
added superdoc as one of the providers
dmonad Jun 19, 2025
61258d8
add blocknote
dmonad Jun 19, 2025
c87430a
add milkdown
dmonad Jun 19, 2025
0b8a0fc
add tiptap
dmonad Jun 19, 2025
b3c92f6
Merge pull request #719 from kasugamirai/chore/readme
dmonad Jun 19, 2025
f4fa053
fix typos
hyonun321 Jun 25, 2025
d5a74c9
Merge pull request #722 from hyonun321/typos
dmonad Jun 26, 2025
f94f2eb
Merge pull request #716 from i3dly/patch-2
dmonad Jun 30, 2025
783a7c4
remove newValue from YEvent
mattkrick Jul 10, 2025
4120d72
Merge pull request #725 from mattkrick/mattkrick-patch-1
dmonad Jul 11, 2025
4738944
Run tests without compilation. optimize testHelper output.
dmonad Mar 25, 2025
cfe67c1
basic delta implementation
dmonad Mar 25, 2025
e13fc60
implement support for diffing deletesets
dmonad Mar 27, 2025
0d3a149
add randomized tests for ds
dmonad Mar 28, 2025
da3cb22
use "insertSet" instead of computing state vectors in transactions
dmonad Apr 8, 2025
c554bd7
add test case for insertSet
dmonad Apr 8, 2025
46347ee
rename DeleteSet=>IdSet and add utilities and perf improvements
dmonad Apr 8, 2025
6360297
doc maintains ds
dmonad Apr 10, 2025
869dd2a
use stores ds to compute state as update
dmonad Apr 10, 2025
a6ae65d
Work on AttributionManager
dmonad Apr 12, 2025
8908bd2
[am] fixed tests
dmonad Apr 12, 2025
a360751
diffing of attribution manager state
dmonad Apr 12, 2025
55238e0
ds is no longer maintained on store - improves perf
dmonad Apr 12, 2025
1d025ae
rename AttributionManager=>IdMap
dmonad Apr 18, 2025
2d87301
implement attribution class that is de-duplicated in IdMap
dmonad Apr 18, 2025
99bcafe
efficient encoding & decoding of IdMaps
dmonad Apr 19, 2025
065f268
more renames (am=>idmap)
dmonad Apr 19, 2025
f78a7d0
more renames (ds=>idset)
dmonad Apr 19, 2025
5f5cf34
implement base AttributionManager class and use in Y.Text
dmonad Apr 20, 2025
2e2968e
attributions and fixes to idmap
dmonad Apr 20, 2025
6671071
first test case for attributions
dmonad Apr 21, 2025
3c37699
basic attribution test working
dmonad Apr 21, 2025
7de9476
attribution tests for adding and removing attributes
dmonad Apr 21, 2025
768d6b1
perf tests toDelta vs getContent
dmonad Apr 22, 2025
69786f7
add another example and create a writeup for attributing content.
dmonad Apr 23, 2025
fbfe0e0
working on performance
dmonad Apr 24, 2025
a6b2dd1
more perf improvements on getContent with attributedContent
dmonad Apr 24, 2025
f5e2a4d
add test case for finding a type in another ydoc
dmonad Apr 24, 2025
d399756
more work on optimizing. Improve the test case.
dmonad Apr 24, 2025
324620d
[attribution manager] returns null instead of empty array to reduce g…
dmonad Apr 27, 2025
ece7466
[AttributionManager] further improve performance to be almost on-par …
dmonad Apr 27, 2025
b3171c5
getContent on Y.Map
dmonad Apr 28, 2025
4f84024
implement and test getContent on all types
dmonad Apr 28, 2025
1722c8a
Implement & test getContentDeep for all types. Improve ability to com…
dmonad Apr 29, 2025
527e382
implement createAttributionsManagerFromDiff that automatically handle…
dmonad Apr 29, 2025
af2ccc7
add an simple attributions example
dmonad Apr 29, 2025
df4a424
lint
dmonad Apr 30, 2025
574892b
14.0.0-2
dmonad Apr 30, 2025
2daad96
implement idset.delete & idmap.delete
dmonad Apr 30, 2025
a43f198
[AttributionManager] auto-updates on doc changes and can destroy itself
dmonad Apr 30, 2025
d8143ef
fix nicks test
dmonad May 1, 2025
7528541
bump y-protocols
dmonad May 1, 2025
397f24b
14.0.0-3
dmonad May 1, 2025
2aba7bf
add missing exports for y-prosemirror
dmonad May 1, 2025
6e98b3f
14.0.0-4
dmonad May 1, 2025
00c2646
[idmap/idset] implement forEach and perf improvement on diffingAttrib…
dmonad May 1, 2025
04c6fbd
fix nicks test case
dmonad May 5, 2025
de12a0f
14.0.0-5
dmonad May 5, 2025
0efa4dd
[diffing] event returns delta class object, migrate away from legacy …
dmonad May 6, 2025
cb191e7
[y.text] event returns delta - fix a bunch of bugs
dmonad May 7, 2025
fc62061
lint & fix tests
dmonad May 7, 2025
6242254
events can be computed with attributions
dmonad May 8, 2025
b646654
be able to intersect idmaps and idsets
dmonad May 9, 2025
4d58274
more generic gedDelta implementation (could be used for events)
dmonad May 18, 2025
7d5d6b8
fix some edge cases
dmonad May 18, 2025
e1ef221
only have a single getDelta implementation for events and retrieving…
dmonad May 19, 2025
3fd60a2
first tests on attributed events
dmonad May 21, 2025
5b29e54
be able to insert into attributed content
dmonad May 21, 2025
43c7521
fix reading content with new api
dmonad May 22, 2025
34b90fc
[attribution] fixes for suggestion support in y-quill
dmonad May 23, 2025
90514dd
more attribution fixes for y-quill
dmonad May 24, 2025
f1ae2a7
suggestion fixes
dmonad May 29, 2025
172b157
fix puzzle1
dmonad May 30, 2025
d9490c4
fix issue with slicing content in attrMngr
dmonad May 31, 2025
6d7ccf6
fix am.readContent
dmonad May 31, 2025
4d50891
fuzz tests for unformatted text run
dmonad Jun 1, 2025
c37ee3e
fix suggestion issues with formatting by introducing an option to dis…
dmonad Jun 2, 2025
e62e1d7
implement StructSet abstraction
dmonad Jun 5, 2025
f41e633
work on allowing skips in struct store
dmonad Jun 5, 2025
78fb8d0
fixed another splicing issue with skips
dmonad Jun 6, 2025
a76d6e1
[skip allowed struct in yjs] fixed all tests
dmonad Jun 6, 2025
8ef8ffc
fix gc splice issues happening in y-quill
dmonad Jun 6, 2025
92bab00
be able to encode partial state with holes correctly
dmonad Jun 7, 2025
74a5a37
DiffAttributionManager supports accepting suggestions
dmonad Jun 8, 2025
10a0198
reject suggestion working
dmonad Jun 9, 2025
a9f802d
fixed a bunch of issues related to attribution of formats
dmonad Jun 9, 2025
9161a96
[delta] useAttributes doesn't clean up empty objects
dmonad Jun 10, 2025
d6a3e63
fixes for accepting / rejecting suggestions
dmonad Jun 10, 2025
5c5139b
handle another attribution edge case for formatting
dmonad Jun 11, 2025
a1a0f44
lint
dmonad Jun 11, 2025
05c79b9
14.0.0-6
dmonad Jun 11, 2025
5e4d240
[suggested formatting] implement previousUnattributedAttributes approach
dmonad Jun 12, 2025
6c78661
lint
dmonad Jun 12, 2025
ab9e726
14.0.0-7
dmonad Jun 12, 2025
e05d538
documentation for attribution feature
dmonad Jun 16, 2025
5000fe5
export createDelta
dmonad Jun 23, 2025
496389e
14.0.0-8
dmonad Jun 23, 2025
72393e6
work on new deltas with modifiers
dmonad Jul 7, 2025
e6ab2bb
major update on the (nested) event system. created dedicated delta cl…
dmonad Jul 19, 2025
5c86133
[readme] add Theneo as a user
dmonad Jul 25, 2025
2f47a98
add reference to lean-yjs
dmonad Sep 15, 2025
91384b5
[wip] refactor for lib0/delta v2
dmonad Oct 20, 2025
c9829b0
fixed most tests for delta v2 migration
dmonad Oct 21, 2025
1ce8154
fixed several v2 issues
dmonad Oct 22, 2025
1b07864
bump to lib0 beta release
dmonad Oct 23, 2025
0435919
no forced tests for release
dmonad Oct 23, 2025
57bc4d3
lint
dmonad Oct 23, 2025
19dbe61
14.0.0-9
dmonad Oct 23, 2025
584ad5f
bump deps and use new delta format
dmonad Oct 28, 2025
029aba4
usability - observeDeep returns function
dmonad Oct 29, 2025
61e3459
lint
dmonad Oct 29, 2025
54c041c
cleanup docs task
dmonad Oct 29, 2025
d298ca9
14.0.0-10
dmonad Oct 29, 2025
2f7895e
fixes and more tests for delta representation on abstract types
dmonad Oct 30, 2025
19b5134
fix all tests
dmonad Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [16.x, 20.x]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
- run: npm test
- run: npm run lint
- run: npm run test
env:
CI: true
31 changes: 0 additions & 31 deletions .github/workflows/nodejs.yml

This file was deleted.

1 change: 1 addition & 0 deletions .well-known/funding-manifest-urls
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://yjs.dev
10 changes: 5 additions & 5 deletions INTERNALS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ article](https://blog.kevinjahns.de/are-crdts-suitable-for-shared-editing/).

Each client is assigned a unique *clientID* property on first insert. This is a
random 53-bit integer (53 bits because that fits in the javascript safe integer
range).
range \[JavaScript uses IEEE 754 floats\]).

## List items

Expand Down Expand Up @@ -60,7 +60,7 @@ characters have either been deleted or all characters are not deleted. The item
will be split if the run is interrupted for any reason (eg a character in the
middle of the run is deleted).

When an item is created, it stores a reference to the IDs of the preceeding and
When an item is created, it stores a reference to the IDs of the preceding and
succeeding item. These are stored in the item's `origin` and `originRight`
fields, respectively. These are used when peers concurrently insert at the same
location in a document. Though quite rare in practice, Yjs needs to make sure
Expand Down Expand Up @@ -88,7 +88,7 @@ When a local insert happens, Yjs needs to map the insert position in the
document (eg position 1000) to an ID. With just the linked list, this would
require a slow O(n) linear scan of the list. But when editing a document, most
inserts are either at the same position as the last insert, or nearby. To
improve performance, Yjs stores a cache of the 10 most recently looked up
improve performance, Yjs stores a cache of the 80 most recently looked up
insert positions in the document. This is consulted and updated when a position
is looked up to improve performance in the average case. The cache is updated
using a heuristic that is still changing (currently, it is updated when a new
Expand Down Expand Up @@ -149,8 +149,8 @@ concepts that can be used to create a custom network protocol:

* `update`: The Yjs document can be encoded to an *update* object that can be
parsed to reconstruct the document. Also every change on the document fires
an incremental document updates that allows clients to sync with each other.
The update object is an Uint8Array that efficiently encodes `Item` objects and
an incremental document update that allows clients to sync with each other.
The update object is a Uint8Array that efficiently encodes `Item` objects and
the delete set.
* `state vector`: A state vector defines the known state of each user (a set of
tuples `(client, clock)`). This object is also efficiently encoded as a
Expand Down
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
The MIT License (MIT)

Copyright (c) 2014
- Kevin Jahns <kevin.jahns@rwth-aachen.de>.
Copyright (c) 2023
- Kevin Jahns <kevin.jahns@protonmail.com>.
- Chair of Computer Science 5 (Databases & Information Systems), RWTH Aachen University, Germany

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
395 changes: 344 additions & 51 deletions README.md

Large diffs are not rendered by default.

121 changes: 121 additions & 0 deletions attributing-content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# IdSets and IdMaps

`IdSet` is a data structure (formerly `DeleteSet`) that allows us to efficiently
represent ranges of ids in Yjs (all content is identifyable by ids).

`IdMap` is a new data structure that allows us to efficiently map ids to
attributes. It can be efficiently encoded.

We can perform all usual set operations on `IdMap`s and `IdSet`s: diff, merge,
intersect.

# Attribution of content

In order to implement a Google Docs-like versioning feature, we want to be able
to attribute content with additional information (who created the change,
when was this change created, ..).

When we click on a version in Google Docs, we might get annotated changes like
this:

```
# E.g. If Bob appends "world" to the previous version "hello "
[{ insert: 'hello' }, { insert: 'world', color: 'blue', creator: 'Bob', when: 'yesterday' }]
# E.g. If Bob deletes "world" from the previous version "hello world"
[{ insert: 'hello' }, { insert: 'world', backgroundColor: 'red', creator: 'Bob', when: 'yesterday' }]
```

In Yjs, we can now "attribute" changes with additional information. When we
render content using methods like `toString()` or `getDelta()`, Yjs will render
the unattributed content as-is, but it will render the attributed content with
the additional information. As all changes in Yjs are identifyable by Ids, we
can use `IdMap`s to map changes to "attributions". For example, we could
attribute deletions and insertions of a change and render them:

```js
// We create some initial content "Hello World!". Then we create another
// document that will have a bunch of changes (make "Hell" italic, replace "World"
// with "Attribution").
const ydocVersion0 = new Y.Doc({ gc: false })
ydocVersion0.getText().insert(0, 'Hello World!')
const ydoc = new Y.Doc({ gc: false })
Y.applyUpdate(ydoc, Y.encodeStateAsUpdate(ydocVersion0))
const ytext = ydoc.getText()
ytext.applyDelta([{ retain: 4, attributes: { italic: true } }, { retain: 2 }, { delete: 5 }, { insert: 'attributions' }])
// this represents to all insertions of ydoc
const insertionSet = Y.createInsertionSetFromStructStore(ydoc.store)
const deleteSet = Y.createDeleteSetFromStructStore(ydoc.store)
// exclude the changes from `ydocVersion0`
const insertionSetDiff = Y.diffIdSet(insertionSet, Y.createInsertionSetFromStructStore(ydocVersion0.store))
const deleteSetDiff = Y.diffIdSet(deleteSet, Y.createDeleteSetFromStructStore(ydocVersion0.store))
// assign attributes to the diff
const attributedInsertions = createIdMapFromIdSet(insertionSetDiff, [new Y.Attribution('insert', 'Bob')])
const attributedDeletions = createIdMapFromIdSet(deleteSetDiff, [new Y.Attribution('delete', 'Bob')])
// now we can define an attribution manager that maps these changes to output. One of the
// implementations is the TwosetAttributionManager
const attributionManager = new TwosetAttributionManager(attributedInsertions, attributedDeletions)
// we render the attributed content with the attributionManager
let attributedContent = ytext.getContent(attributionManager)
console.log(JSON.stringify(attributedContent.toJSON().ops, null, 2))
let expectedContent = delta.create().insert('Hell', { italic: true }, { attributes: { italic: ['Bob'] } }).insert('o ').insert('World', {}, { delete: ['Bob'] }).insert('attributions', {}, { insert: ['Bob'] }).insert('!')
t.assert(attributedContent.equals(expectedContent))

// this is how the output would look like
const output = [
{
"insert": "Hell",
"attributes": {
"italic": true
},
"attribution": { // no "insert" attribution: the insertion "Hell" is not attributed to anyone
"attributes": {
"italic": [ // the attribute "italic" was added by Bob
"Bob"
]
}
}
},
{
"insert": "o " // the insertion "o " has no attributions
},
{
"insert": "World",
"attribution": { // the insertion "World" was deleted by Bob
"delete": [
"Bob"
]
}
},
{
"insert": "attributions", // the insertion "attributions" was inserted by Bob
"attribution": {
"insert": [
"Bob"
]
}
},
{
"insert": "!" // the insertion "!" has no attributions
}
]
```

We get a similar output to Google Docs: Insertions, Deletions, and changes to
formatting (attributes) are clearly associated to users. It will be the job of
the editor to render those changes with background-color etc..

Of course, we could associated changes also to multiple users like this:

```js
const attributedDeletions = createIdMapFromIdSet(deleteSetDiff, [new Y.Attribution('insert', 'Bob'), new Y.Attribution('insert', 'OpenAI o3')])
```

You could use the same output to calculate a real diff as well (consisting of
deletions and insertions only, without Attributions).

`AttributionManager` is an abstract class for mapping attributions. It is
possible to highlight arbitrary content with this approach.

The AttributionManager is encodes very efficiently. The ids are encoded using
run-length encoding and the Attributes are de-duplicated and only encoded once.
The above example encodes in 20 bytes.
Loading