diff --git a/backend/src/realtime/realtime-note/realtime-note-store.ts b/backend/src/realtime/realtime-note/realtime-note-store.ts index 8236e29de..0503d8f70 100644 --- a/backend/src/realtime/realtime-note/realtime-note-store.ts +++ b/backend/src/realtime/realtime-note/realtime-note-store.ts @@ -31,7 +31,7 @@ export class RealtimeNoteStore { const realtimeNote = new RealtimeNote( noteId, initialTextContent, - initialYjsState, + initialYjsState ? Array.from(new Uint8Array(initialYjsState)) : undefined, ); realtimeNote.on('destroy', () => { this.noteIdToRealtimeNote.delete(noteId); diff --git a/backend/src/realtime/realtime-note/realtime-note.service.ts b/backend/src/realtime/realtime-note/realtime-note.service.ts index e3c064e31..800c1d363 100644 --- a/backend/src/realtime/realtime-note/realtime-note.service.ts +++ b/backend/src/realtime/realtime-note/realtime-note.service.ts @@ -49,7 +49,7 @@ export class RealtimeNoteService implements BeforeApplicationShutdown { realtimeNote.getRealtimeDoc().getCurrentContent(), false, undefined, - realtimeNote.getRealtimeDoc().encodeStateAsUpdate(), + new Uint8Array(realtimeNote.getRealtimeDoc().encodeStateAsUpdate()), ) .then(() => { realtimeNote.announceMetadataUpdate(); diff --git a/backend/src/realtime/realtime-note/realtime-note.ts b/backend/src/realtime/realtime-note/realtime-note.ts index f97f85d49..ad6d003c5 100644 --- a/backend/src/realtime/realtime-note/realtime-note.ts +++ b/backend/src/realtime/realtime-note/realtime-note.ts @@ -34,7 +34,7 @@ export class RealtimeNote extends EventEmitter2 { constructor( private readonly noteId: number, initialTextContent: string, - initialYjsState?: ArrayBuffer, + initialYjsState?: number[], ) { super(); this.logger = new Logger(`${RealtimeNote.name} ${noteId}`); diff --git a/commons/src/message-transporters/message.ts b/commons/src/message-transporters/message.ts index b66b2efc4..1fcb53112 100644 --- a/commons/src/message-transporters/message.ts +++ b/commons/src/message-transporters/message.ts @@ -29,8 +29,8 @@ export enum ConnectionStateEvent { } export interface MessagePayloads { - [MessageType.NOTE_CONTENT_STATE_REQUEST]: ArrayBuffer - [MessageType.NOTE_CONTENT_UPDATE]: ArrayBuffer + [MessageType.NOTE_CONTENT_STATE_REQUEST]: number[] + [MessageType.NOTE_CONTENT_UPDATE]: number[] [MessageType.REALTIME_USER_STATE_SET]: { users: RealtimeUser[] ownUser: { diff --git a/commons/src/y-doc-sync/realtime-doc.spec.ts b/commons/src/y-doc-sync/realtime-doc.spec.ts index 7743ffeec..dd00e52ed 100644 --- a/commons/src/y-doc-sync/realtime-doc.spec.ts +++ b/commons/src/y-doc-sync/realtime-doc.spec.ts @@ -21,12 +21,12 @@ describe('realtime doc', () => { it('restores a yjs state vector update correctly', () => { const realtimeDoc = new RealtimeDoc( 'notTheVectorText', - new Uint8Array([ + [ 1, 1, 221, 208, 165, 230, 3, 0, 4, 1, 15, 109, 97, 114, 107, 100, 111, 119, 110, 67, 111, 110, 116, 101, 110, 116, 32, 116, 101, 120, 116, 67, 111, 110, 116, 101, 110, 116, 70, 114, 111, 109, 83, 116, 97, 116, 101, 86, 101, 99, 116, 111, 114, 85, 112, 100, 97, 116, 101, 0, - ]), + ], ) expect(realtimeDoc.getCurrentContent()).toBe( diff --git a/commons/src/y-doc-sync/realtime-doc.ts b/commons/src/y-doc-sync/realtime-doc.ts index 31db78171..3b8a337db 100644 --- a/commons/src/y-doc-sync/realtime-doc.ts +++ b/commons/src/y-doc-sync/realtime-doc.ts @@ -16,7 +16,7 @@ import { const MARKDOWN_CONTENT_CHANNEL_NAME = 'markdownContent' export interface RealtimeDocEvents extends EventMap { - update: (update: ArrayBuffer, origin: unknown) => void + update: (update: number[], origin: unknown) => void } /** @@ -37,16 +37,26 @@ export class RealtimeDoc extends EventEmitter2 { * @param initialTextContent the initial text content of the {@link Doc YDoc} * @param initialYjsState the initial yjs state. If provided this will be used instead of the text content */ - constructor(initialTextContent?: string, initialYjsState?: ArrayBuffer) { + constructor(initialTextContent?: string, initialYjsState?: number[]) { super() - if (initialYjsState) { + console.debug( + 'Creating new RealtimeDoc', + 'initialYjsState', + initialYjsState, + 'initialTextContent', + initialTextContent, + ) + if (initialYjsState !== undefined) { + console.debug('Applying update') this.applyUpdate(initialYjsState, this) - } else if (initialTextContent) { + } else if (initialTextContent !== undefined) { + console.debug('Setting initial text content') this.getMarkdownContentChannel().insert(0, initialTextContent) } + console.debug('Setting up listeners') this.docUpdateListener = (update, origin) => { - this.emit('update', update, origin) + this.emit('update', Array.from(update), origin) } this.doc.on('update', this.docUpdateListener) } @@ -77,13 +87,12 @@ export class RealtimeDoc extends EventEmitter2 { * * @param encodedTargetStateVector The current state vector of the other y-doc. If provided the update will contain only the differences. */ - public encodeStateAsUpdate( - encodedTargetStateVector?: ArrayBuffer, - ): ArrayBuffer { - const update = encodedTargetStateVector - ? new Uint8Array(encodedTargetStateVector) - : undefined - return encodeStateAsUpdate(this.doc, update) + public encodeStateAsUpdate(encodedTargetStateVector?: number[]): number[] { + const update = + encodedTargetStateVector !== undefined + ? new Uint8Array(encodedTargetStateVector) + : undefined + return Array.from(encodeStateAsUpdate(this.doc, update)) } public destroy(): void { @@ -97,11 +106,11 @@ export class RealtimeDoc extends EventEmitter2 { * @param payload The update to apply * @param origin A reference that triggered the update */ - public applyUpdate(payload: ArrayBuffer, origin: unknown): void { + public applyUpdate(payload: number[], origin: unknown): void { applyUpdate(this.doc, new Uint8Array(payload), origin) } - public encodeStateVector(): ArrayBuffer { - return encodeStateVector(this.doc) + public encodeStateVector(): number[] { + return Array.from(encodeStateVector(this.doc)) } } diff --git a/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts b/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts index baf51f6b6..d2c6c9d53 100644 --- a/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts +++ b/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts @@ -104,7 +104,7 @@ describe('y-doc-sync-adapter', () => { console.log('s>2 is connected'), ) - docServer.on('update', (update: ArrayBuffer, origin: unknown) => { + docServer.on('update', (update: number[], origin: unknown) => { const message: Message = { type: MessageType.NOTE_CONTENT_UPDATE, payload: update, @@ -118,12 +118,12 @@ describe('y-doc-sync-adapter', () => { messageTransporterServerTo2.sendMessage(message) } }) - docClient1.on('update', (update: ArrayBuffer, origin: unknown) => { + docClient1.on('update', (update: number[], origin: unknown) => { if (origin !== messageTransporterClient1) { console.log('YDoc on client 1 updated. Sending to Server') } }) - docClient2.on('update', (update: ArrayBuffer, origin: unknown) => { + docClient2.on('update', (update: number[], origin: unknown) => { if (origin !== messageTransporterClient2) { console.log('YDoc on client 2 updated. Sending to Server') } diff --git a/commons/src/y-doc-sync/y-doc-sync-adapter.ts b/commons/src/y-doc-sync/y-doc-sync-adapter.ts index b3c77bd28..752692dca 100644 --- a/commons/src/y-doc-sync/y-doc-sync-adapter.ts +++ b/commons/src/y-doc-sync/y-doc-sync-adapter.ts @@ -97,11 +97,11 @@ export abstract class YDocSyncAdapter { } } - protected applyIncomingUpdatePayload(update: ArrayBuffer): void { + protected applyIncomingUpdatePayload(update: number[]): void { this.doc.applyUpdate(update, this) } - private distributeDocUpdate(update: ArrayBuffer, origin: unknown): void { + private distributeDocUpdate(update: number[], origin: unknown): void { if (!this.isSynced() || origin === this) { return } diff --git a/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts b/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts index aa1ec4bc2..396bc19a2 100644 --- a/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts +++ b/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts @@ -17,7 +17,7 @@ export class YDocSyncServerAdapter extends YDocSyncAdapter { this.markAsSynced() } - protected applyIncomingUpdatePayload(update: ArrayBuffer): void { + protected applyIncomingUpdatePayload(update: number[]): void { if (!this.acceptEditsProvider()) { return }