diff --git a/packages/tlsync/src/lib/RoomSession.ts b/packages/tlsync/src/lib/RoomSession.ts index 69c25be0a..b4b3f45bc 100644 --- a/packages/tlsync/src/lib/RoomSession.ts +++ b/packages/tlsync/src/lib/RoomSession.ts @@ -33,6 +33,7 @@ export type RoomSession = state: typeof RoomSessionState.Connected sessionKey: string presenceId: string + isV4Client: boolean socket: TLRoomSocket serializedSchema: SerializedSchema lastInteractionTime: number diff --git a/packages/tlsync/src/lib/TLSyncClient.ts b/packages/tlsync/src/lib/TLSyncClient.ts index 987042531..46b0b99e6 100644 --- a/packages/tlsync/src/lib/TLSyncClient.ts +++ b/packages/tlsync/src/lib/TLSyncClient.ts @@ -367,6 +367,13 @@ export class TLSyncClient = Store console.error('Restarting socket') this.socket.restart() break + // legacy v4 events + case 'patch': + case 'push_result': + if (!this.isConnectedToRoom) break + this.incomingDiffBuffer.push(event) + this.scheduleRebase() + break case 'data': // wait for a connect to succeed before processing more events if (!this.isConnectedToRoom) break diff --git a/packages/tlsync/src/lib/TLSyncRoom.ts b/packages/tlsync/src/lib/TLSyncRoom.ts index 25b643028..a815329e2 100644 --- a/packages/tlsync/src/lib/TLSyncRoom.ts +++ b/packages/tlsync/src/lib/TLSyncRoom.ts @@ -413,7 +413,9 @@ export class TLSyncRoom { } else { if (session.debounceTimer === null) { // this is the first message since the last flush, don't delay it - session.socket.sendMessage({ type: 'data', data: [message] }) + session.socket.sendMessage( + session.isV4Client ? message : { type: 'data', data: [message] } + ) session.debounceTimer = setTimeout( () => this._flushDataMessages(sessionKey), @@ -440,7 +442,14 @@ export class TLSyncRoom { session.debounceTimer = null if (session.outstandingDataMessages.length > 0) { - session.socket.sendMessage({ type: 'data', data: session.outstandingDataMessages }) + if (session.isV4Client) { + // v4 clients don't support the "data" message, so we need to send each message separately + for (const message of session.outstandingDataMessages) { + session.socket.sendMessage(message) + } + } else { + session.socket.sendMessage({ type: 'data', data: session.outstandingDataMessages }) + } session.outstandingDataMessages.length = 0 } } @@ -662,7 +671,11 @@ export class TLSyncRoom { // if the protocol versions don't match, disconnect the client // we will eventually want to try to make our protocol backwards compatible to some degree // and have a MIN_PROTOCOL_VERSION constant that the TLSyncRoom implements support for - if (message.protocolVersion == null || message.protocolVersion < TLSYNC_PROTOCOL_VERSION) { + const isV4Client = message.protocolVersion === 4 && TLSYNC_PROTOCOL_VERSION === 5 + if ( + message.protocolVersion == null || + (message.protocolVersion < TLSYNC_PROTOCOL_VERSION && !isV4Client) + ) { this.rejectSession(session, TLIncompatibilityReason.ClientTooOld) return } else if (message.protocolVersion > TLSYNC_PROTOCOL_VERSION) { @@ -688,6 +701,7 @@ export class TLSyncRoom { state: RoomSessionState.Connected, sessionKey: session.sessionKey, presenceId: session.presenceId, + isV4Client, socket: session.socket, serializedSchema: sessionSchema, lastInteractionTime: Date.now(), diff --git a/packages/tlsync/src/lib/protocol.ts b/packages/tlsync/src/lib/protocol.ts index d7ca22cd8..9bc21d364 100644 --- a/packages/tlsync/src/lib/protocol.ts +++ b/packages/tlsync/src/lib/protocol.ts @@ -39,6 +39,7 @@ export type TLSocketServerSentEvent = type: 'pong' } | { type: 'data'; data: TLSocketServerSentDataEvent[] } + | TLSocketServerSentDataEvent /** @public */ export type TLSocketServerSentDataEvent = diff --git a/packages/tlsync/src/test/upgradeDowngrade.test.ts b/packages/tlsync/src/test/upgradeDowngrade.test.ts index 58f8d5317..c984fdc8c 100644 --- a/packages/tlsync/src/test/upgradeDowngrade.test.ts +++ b/packages/tlsync/src/test/upgradeDowngrade.test.ts @@ -362,7 +362,7 @@ test('clients using an out-of-date protocol will receive compatibility errors', type: 'connect', connectRequestId: 'test', lastServerClock: 0, - protocolVersion: TLSYNC_PROTOCOL_VERSION - 1, + protocolVersion: TLSYNC_PROTOCOL_VERSION - 2, schema: schemaV2.serialize(), })