Skip to content

Commit dca410a

Browse files
committed
fix(sync): bump version after loading document state
* Emit the documents last saved version in the push response if document state is send as well. * Otherwise send the version as 0 so it cannot increase the sync service version. * Use the versions returned by create and push requests alongside the document state to construct a consistent step with the last saved version that matches the document state. This will result in the sync service version getting bumped to the documents last saved version once the coresponding document state has been processed. Signed-off-by: Max <max@nextcloud.com>
1 parent cbbf4ec commit dca410a

3 files changed

Lines changed: 10 additions & 9 deletions

File tree

lib/Service/DocumentService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ public function addStep(Document $document, Session $session, array $steps, int
265265

266266
return [
267267
'steps' => $stepsToReturn,
268-
'version' => $newVersion,
268+
'version' => isset($documentState) ? $document->getLastSavedVersion() : 0,
269269
'documentState' => $documentState
270270
];
271271
}

src/helpers/yjs.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ export function applyDocumentState(
4343
* and encode it and wrap it in a step data structure.
4444
*
4545
* @param documentState - base64 encoded doc state
46+
* @param version - last saved version for the document state
4647
* @return base64 encoded yjs sync protocol update message and version
4748
*/
48-
export function documentStateToStep(documentState: string): Step {
49+
export function documentStateToStep(documentState: string, version: number): Step {
4950
const message = documentStateToUpdateMessage(documentState)
50-
return { data: [encodeArrayBuffer(message)], sessionId: 0, version: -1 }
51+
return { data: [encodeArrayBuffer(message)], sessionId: 0, version }
5152
}
5253

5354
/**

src/services/SyncService.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,12 @@ class SyncService {
173173
console.error('Opened the connection but now it is undefined')
174174
return
175175
}
176-
this.version = data.document.lastSavedVersion
177176
this.backend = new PollingBackend(this, this.connection.value, data)
178177
// Make sure to only emit this once the backend is in place.
179178
this.bus.emit('opened', data)
180179
// Emit sync after opened, so websocket onmessage comes after onopen.
181180
if (data.documentState) {
182-
this._emitDocumentStateStep(data.documentState)
181+
this._emitDocumentStateStep(data.documentState, data.document.lastSavedVersion)
183182
}
184183
}
185184

@@ -202,8 +201,8 @@ class SyncService {
202201
}
203202
}
204203

205-
_emitDocumentStateStep(documentState: string) {
206-
const documentStateStep = documentStateToStep(documentState)
204+
_emitDocumentStateStep(documentState: string, version: number) {
205+
const documentStateStep = documentStateToStep(documentState, version)
207206
this.bus.emit('sync', {
208207
steps: [documentStateStep],
209208
})
@@ -249,12 +248,13 @@ class SyncService {
249248
})
250249
.then((response) => {
251250
this.#outbox.clearSentData(sendable)
252-
const { steps, documentState } = response.data as {
251+
const { steps, documentState, version } = response.data as {
253252
steps: Step[]
254253
documentState: string
254+
version: number
255255
}
256256
if (documentState) {
257-
this._emitDocumentStateStep(documentState)
257+
this._emitDocumentStateStep(documentState, version)
258258
}
259259
this.pushError = 0
260260
this.#sending = false

0 commit comments

Comments
 (0)