I explored several options based on the the previous discussions. It seems I can’t reach promise land yet.
The first option is the following:
I am creating a snapshot of the document and adding it into an YArray in the desired YDoc. Something like this:
export const addSnapshotOnYDoc = (document: Y.Doc): void => {
document.gc = false
const versions = document.getArray<YDocVersion>('versions')
const prevVersion = versions.length === 0 ? null : versions.get(0)
const prevSnapshot: Y.Snapshot =
prevVersion === null
? Y.emptySnapshot
: Y.decodeSnapshot(prevVersion.snapshot)
const snapshot: Y.Snapshot = Y.snapshot(document)
if (!Y.equalSnapshots(prevSnapshot, snapshot)) {
versions.delete(0, versions.length)
versions.insert(0, [
{
date: new Date().getTime(),
snapshot: Y.encodeSnapshot(snapshot),
clientID: document.clientID,
},
])
}
}
I am interested in saving only the last version of the document, and only once, so I don’t care treating multiple versions scenarios for the moment.
From here I tried 2 approaches:
- Trying to get the decoded diffs between the currentDoc and the snapshotedVersion of the doc.:
export const diffYjsDocs = (document: Y.Doc) => {
document.gc = false
const versions = document.getArray<YDocVersion>('versions')
const prevVersion = versions.length === 0 ? null : versions.get(0)
if (!prevVersion) {
return...
}
const docFromSnapshot = Y.createDocFromSnapshot(
document,
Y.decodeSnapshot(prevVersion.snapshot)
)
const ydoc1State = Y.encodeStateAsUpdate(document)
const ydoc2State = Y.encodeStateAsUpdate(docFromSnapshot)
const stateVector2 = Y.encodeStateVectorFromUpdate(ydoc2State)
const diff = Y.diffUpdate(ydoc1State, stateVector2)
const decodedDiff = Y.decodeUpdate(diff)
console.log({ decodedDiff })
}
It seems this approach works only for added “nodes”, not for changed/removed ones.
- Trying to observe the structure that is being changed inside both documents, and diff the deltas as suggested. Here I couldn’t find a way to make the observer trigger upon
Y.createDocFromSnapshot
. I had to applyUpdate
in order to trigger the observer, even tho behind the scenes, createDocFromSnapshot
also uses applyUpdate`. So I am trying to do something like this:
const diffDeltaChanges = (originalDelta: string) => {
let originalDeltas: Delta = []
let currentDeltas: Delta = [];
const originalDocDelta = toUint8Array(response.delta);
document.gc = false;
let originalDoc = new Y.Doc();
const currentSharedRoot = editor.sharedRoot;
const sharedRoot = originalDoc.get('content', Y.XmlText) as Y.XmlText;
sharedRoot.observe(event => {
const deltas = event.changes.delta as Delta
originalDeltas = deltas;
});
currentSharedRoot.observe(event => {
const deltas = event.changes.delta as Delta;
currentDeltas = deltas;
});
// I can see only insert deltas, but when I am changing some item attributes,
// or delete some, this is not represented in deltas or changes.
}
Also, if I am comparing deltas, e.g.:
initialDoc: 2 deltas
currentDoc: 5 deltas
I might get the diff between them as added items.
But if I do change the item[0] contained in both initialDoc
& currentDoc
, this doesn’t reflected in deltas.
Same for removing a common element from both docs.
Not sure what I am doing wrong in this case.