Allow clients to gracefully handle rejection (#3673)
This PR fixes the issue where sync clients would get into a reconnect loop after being rejected by the sync server. - Close the socket when in the error state (see useRemoteSyncClient) - Show a 'plx refresh the page' screen that doesn't have a sad face on it. <img width="665" alt="image" src="https://github.com/tldraw/tldraw/assets/1242537/96025fa3-cc20-4f53-8f58-74e473e16702"> - If older clients who can't handle rejection well need to be rejected (e.g. due to a store migration being added) then we send them to a special purgatory where the canvas goes blank and it shows the offline indicator but the websocket connection stays open and it won't try to reconnect. ### Change Type - [x] `dotcom` — Changes the tldraw.com web app - [x] `bugfix` — Bug fix ### Test Plan 1. Gonna manually test this one by doing sneaky deploys to a test PR
This commit is contained in:
parent
e999316691
commit
f2827f6409
15 changed files with 143 additions and 68 deletions
|
@ -1,28 +1,39 @@
|
|||
import { ReactNode } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { isInIframe } from '../../utils/iFrame'
|
||||
|
||||
export function ErrorPage({
|
||||
icon,
|
||||
messages,
|
||||
}: {
|
||||
icon?: boolean
|
||||
messages: { header: string; para1: string; para2?: string }
|
||||
}) {
|
||||
const GoBackLink = () => {
|
||||
const inIframe = isInIframe()
|
||||
return (
|
||||
<Link to={'/'} target={inIframe ? '_blank' : '_self'}>
|
||||
{inIframe ? 'Open tldraw.' : 'Back to tldraw.'}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
const sadFaceIcon = (
|
||||
<img width={36} height={36} src="/404-Sad-tldraw.svg" loading="lazy" role="presentation" />
|
||||
)
|
||||
|
||||
export function ErrorPage({
|
||||
messages,
|
||||
icon = sadFaceIcon,
|
||||
cta = <GoBackLink />,
|
||||
}: {
|
||||
icon?: ReactNode
|
||||
messages: { header: string; para1: string; para2?: string }
|
||||
cta?: ReactNode
|
||||
}) {
|
||||
return (
|
||||
<div className="error-page">
|
||||
<div className="error-page__container">
|
||||
{icon && (
|
||||
<img width={36} height={36} alt={'Not found'} src="/404-Sad-tldraw.svg" loading="lazy" />
|
||||
)}
|
||||
{icon}
|
||||
<div className="error-page__content">
|
||||
<h1>{messages.header}</h1>
|
||||
<p>{messages.para1}</p>
|
||||
{messages.para2 && <p>{messages.para2}</p>}
|
||||
</div>
|
||||
<Link to={'/'} target={inIframe ? '_blank' : '_self'}>
|
||||
{inIframe ? 'Open tldraw.' : 'Back to tldraw.'}
|
||||
</Link>
|
||||
{cta}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,17 +1,33 @@
|
|||
import { TLIncompatibilityReason } from '@tldraw/tlsync'
|
||||
import { exhaustiveSwitchError } from 'tldraw'
|
||||
import 'tldraw/tldraw.css'
|
||||
import { RemoteSyncError } from '../utils/remote-sync/remote-sync'
|
||||
import { ErrorPage } from './ErrorPage/ErrorPage'
|
||||
|
||||
export function StoreErrorScreen({ error }: { error: Error }) {
|
||||
let header = 'Could not connect to server.'
|
||||
let message = ''
|
||||
|
||||
if (error instanceof RemoteSyncError) {
|
||||
switch (error.reason) {
|
||||
case TLIncompatibilityReason.ClientTooOld: {
|
||||
message = 'This client is out of date. Please refresh the page.'
|
||||
break
|
||||
return (
|
||||
<ErrorPage
|
||||
icon={
|
||||
<img
|
||||
width={36}
|
||||
height={36}
|
||||
src="/tldraw-white-on-black.svg"
|
||||
loading="lazy"
|
||||
role="presentation"
|
||||
/>
|
||||
}
|
||||
messages={{
|
||||
header: 'Refresh the page',
|
||||
para1: 'You need to update to the latest version of tldraw to continue.',
|
||||
}}
|
||||
cta={<button onClick={() => window.location.reload()}>Refresh</button>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
case TLIncompatibilityReason.ServerTooOld: {
|
||||
message =
|
||||
|
@ -38,5 +54,5 @@ export function StoreErrorScreen({ error }: { error: Error }) {
|
|||
}
|
||||
}
|
||||
|
||||
return <ErrorPage icon messages={{ header, para1: message }} />
|
||||
return <ErrorPage messages={{ header, para1: message }} />
|
||||
}
|
||||
|
|
|
@ -40,7 +40,11 @@ export function useRemoteSyncClient(opts: UseSyncClientConfig): RemoteTLStoreWit
|
|||
|
||||
const store = useTLStore({ schema })
|
||||
|
||||
const error: NonNullable<typeof state>['error'] = state?.error ?? undefined
|
||||
|
||||
useEffect(() => {
|
||||
if (error) return
|
||||
|
||||
const userPreferences = computed<{ id: string; color: string; name: string }>(
|
||||
'userPreferences',
|
||||
() => {
|
||||
|
@ -107,7 +111,7 @@ export function useRemoteSyncClient(opts: UseSyncClientConfig): RemoteTLStoreWit
|
|||
client.close()
|
||||
socket.close()
|
||||
}
|
||||
}, [prefs, roomId, store, uri])
|
||||
}, [prefs, roomId, store, uri, error])
|
||||
|
||||
return useValue<RemoteTLStoreWithStatus>(
|
||||
'remote synced store',
|
||||
|
|
|
@ -28,7 +28,6 @@ export function Component() {
|
|||
if (!result || !result.timestamp)
|
||||
return (
|
||||
<ErrorPage
|
||||
icon
|
||||
messages={{
|
||||
header: 'Page not found',
|
||||
para1: 'The page you are looking does not exist or has been moved.',
|
||||
|
|
|
@ -25,7 +25,6 @@ export function Component() {
|
|||
if (!data)
|
||||
return (
|
||||
<ErrorPage
|
||||
icon
|
||||
messages={{
|
||||
header: 'Page not found',
|
||||
para1: 'The page you are looking does not exist or has been moved.',
|
||||
|
|
|
@ -29,7 +29,6 @@ export function Component() {
|
|||
if (!data)
|
||||
return (
|
||||
<ErrorPage
|
||||
icon
|
||||
messages={{
|
||||
header: 'Page not found',
|
||||
para1: 'The page you are looking does not exist or has been moved.',
|
||||
|
|
|
@ -3,7 +3,6 @@ import { ErrorPage } from '../components/ErrorPage/ErrorPage'
|
|||
export function Component() {
|
||||
return (
|
||||
<ErrorPage
|
||||
icon
|
||||
messages={{
|
||||
header: 'Page not found',
|
||||
para1: 'The page you are looking does not exist or has been moved.',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { TLSocketClientSentEvent, TLSYNC_PROTOCOL_VERSION } from '@tldraw/tlsync'
|
||||
import { TLSocketClientSentEvent, getTlsyncProtocolVersion } from '@tldraw/tlsync'
|
||||
import { TLRecord } from 'tldraw'
|
||||
import { ClientWebSocketAdapter, INACTIVE_MIN_DELAY } from './ClientWebSocketAdapter'
|
||||
// NOTE: there is a hack in apps/dotcom/jestResolver.js to make this import work
|
||||
|
@ -141,7 +141,7 @@ describe(ClientWebSocketAdapter, () => {
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
schema: { schemaVersion: 1, storeVersion: 0, recordVersions: {} },
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
lastServerClock: 0,
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ export {
|
|||
} from './lib/diff'
|
||||
export {
|
||||
TLIncompatibilityReason,
|
||||
TLSYNC_PROTOCOL_VERSION,
|
||||
getTlsyncProtocolVersion,
|
||||
type TLConnectRequest,
|
||||
type TLPingRequest,
|
||||
type TLPushRequest,
|
||||
|
|
|
@ -33,7 +33,6 @@ export type RoomSession<R extends UnknownRecord> =
|
|||
state: typeof RoomSessionState.Connected
|
||||
sessionKey: string
|
||||
presenceId: string
|
||||
isV4Client: boolean
|
||||
socket: TLRoomSocket<R>
|
||||
serializedSchema: SerializedSchema
|
||||
lastInteractionTime: number
|
||||
|
|
|
@ -15,10 +15,10 @@ import { interval } from './interval'
|
|||
import {
|
||||
TLIncompatibilityReason,
|
||||
TLPushRequest,
|
||||
TLSYNC_PROTOCOL_VERSION,
|
||||
TLSocketClientSentEvent,
|
||||
TLSocketServerSentDataEvent,
|
||||
TLSocketServerSentEvent,
|
||||
getTlsyncProtocolVersion,
|
||||
} from './protocol'
|
||||
import './requestAnimationFrame.polyfill'
|
||||
|
||||
|
@ -272,7 +272,7 @@ export class TLSyncClient<R extends UnknownRecord, S extends Store<R> = Store<R>
|
|||
type: 'connect',
|
||||
connectRequestId: this.latestConnectRequestId,
|
||||
schema: this.store.schema.serialize(),
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
lastServerClock: this.lastServerClock,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -41,10 +41,10 @@ import {
|
|||
import { interval } from './interval'
|
||||
import {
|
||||
TLIncompatibilityReason,
|
||||
TLSYNC_PROTOCOL_VERSION,
|
||||
TLSocketClientSentEvent,
|
||||
TLSocketServerSentDataEvent,
|
||||
TLSocketServerSentEvent,
|
||||
getTlsyncProtocolVersion,
|
||||
} from './protocol'
|
||||
|
||||
/** @public */
|
||||
|
@ -420,9 +420,7 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
} else {
|
||||
if (session.debounceTimer === null) {
|
||||
// this is the first message since the last flush, don't delay it
|
||||
session.socket.sendMessage(
|
||||
session.isV4Client ? message : { type: 'data', data: [message] }
|
||||
)
|
||||
session.socket.sendMessage({ type: 'data', data: [message] })
|
||||
|
||||
session.debounceTimer = setTimeout(
|
||||
() => this._flushDataMessages(sessionKey),
|
||||
|
@ -449,14 +447,7 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
session.debounceTimer = null
|
||||
|
||||
if (session.outstandingDataMessages.length > 0) {
|
||||
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.socket.sendMessage({ type: 'data', data: session.outstandingDataMessages })
|
||||
session.outstandingDataMessages.length = 0
|
||||
}
|
||||
}
|
||||
|
@ -678,14 +669,15 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
// 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
|
||||
const isV4Client = message.protocolVersion === 4 && TLSYNC_PROTOCOL_VERSION === 5
|
||||
if (
|
||||
message.protocolVersion == null ||
|
||||
(message.protocolVersion < TLSYNC_PROTOCOL_VERSION && !isV4Client)
|
||||
) {
|
||||
let theirProtocolVersion = message.protocolVersion
|
||||
// 5 is the same as 6
|
||||
if (theirProtocolVersion === 5) {
|
||||
theirProtocolVersion = 6
|
||||
}
|
||||
if (theirProtocolVersion == null || theirProtocolVersion < getTlsyncProtocolVersion()) {
|
||||
this.rejectSession(session, TLIncompatibilityReason.ClientTooOld)
|
||||
return
|
||||
} else if (message.protocolVersion > TLSYNC_PROTOCOL_VERSION) {
|
||||
} else if (theirProtocolVersion > getTlsyncProtocolVersion()) {
|
||||
this.rejectSession(session, TLIncompatibilityReason.ServerTooOld)
|
||||
return
|
||||
}
|
||||
|
@ -711,7 +703,6 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
state: RoomSessionState.Connected,
|
||||
sessionKey: session.sessionKey,
|
||||
presenceId: session.presenceId,
|
||||
isV4Client,
|
||||
socket: session.socket,
|
||||
serializedSchema: sessionSchema,
|
||||
lastInteractionTime: Date.now(),
|
||||
|
@ -751,7 +742,7 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
type: 'connect',
|
||||
connectRequestId: message.connectRequestId,
|
||||
hydrationType: 'wipe_all',
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: this.schema.serialize(),
|
||||
serverClock: this.clock,
|
||||
diff: migrated.value,
|
||||
|
@ -797,7 +788,7 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
connectRequestId: message.connectRequestId,
|
||||
hydrationType: 'wipe_presence',
|
||||
schema: this.schema.serialize(),
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
serverClock: this.clock,
|
||||
diff: migrated.value,
|
||||
})
|
||||
|
|
|
@ -2,7 +2,11 @@ import { SerializedSchema, UnknownRecord } from '@tldraw/store'
|
|||
import { NetworkDiff, ObjectDiff, RecordOpType } from './diff'
|
||||
|
||||
/** @public */
|
||||
export const TLSYNC_PROTOCOL_VERSION = 5
|
||||
const TLSYNC_PROTOCOL_VERSION = 6
|
||||
|
||||
export function getTlsyncProtocolVersion() {
|
||||
return TLSYNC_PROTOCOL_VERSION
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const TLIncompatibilityReason = {
|
||||
|
|
|
@ -14,7 +14,7 @@ import { DBLoadResult, TLServer } from '../lib/TLServer'
|
|||
import { RoomSnapshot } from '../lib/TLSyncRoom'
|
||||
import { chunk } from '../lib/chunk'
|
||||
import { RecordOpType } from '../lib/diff'
|
||||
import { TLSYNC_PROTOCOL_VERSION, TLSocketClientSentEvent } from '../lib/protocol'
|
||||
import { TLSocketClientSentEvent, getTlsyncProtocolVersion } from '../lib/protocol'
|
||||
import { RoomState } from '../lib/server-types'
|
||||
|
||||
// Because we are using jsdom in this package, jest tries to load the 'browser' version of the ws library
|
||||
|
@ -145,7 +145,7 @@ describe('TLServer', () => {
|
|||
type: 'connect',
|
||||
lastServerClock: 0,
|
||||
connectRequestId: 'test-connect-request-id',
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,24 @@ import { RoomSnapshot, TLRoomSocket } from '../lib/TLSyncRoom'
|
|||
import { RecordOpType, ValueOpType } from '../lib/diff'
|
||||
import {
|
||||
TLIncompatibilityReason,
|
||||
TLSYNC_PROTOCOL_VERSION,
|
||||
TLSocketServerSentEvent,
|
||||
getTlsyncProtocolVersion,
|
||||
} from '../lib/protocol'
|
||||
import { TestServer } from './TestServer'
|
||||
import { TestSocketPair } from './TestSocketPair'
|
||||
|
||||
const actualProtocol = jest.requireActual('../lib/protocol')
|
||||
|
||||
jest.mock('../lib/protocol', () => {
|
||||
const actual = jest.requireActual('../lib/protocol')
|
||||
return {
|
||||
...actual,
|
||||
getTlsyncProtocolVersion: jest.fn(actual.getTlsyncProtocolVersion),
|
||||
}
|
||||
})
|
||||
|
||||
const mockGetTlsyncProtocolVersion = getTlsyncProtocolVersion as jest.Mock
|
||||
|
||||
function mockSocket<R extends UnknownRecord>(): TLRoomSocket<R> {
|
||||
return {
|
||||
isOpen: true,
|
||||
|
@ -328,7 +340,7 @@ test('clients will receive updates from a snapshot migration upon connection', (
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: snapshot.clock,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV3.serialize(),
|
||||
})
|
||||
|
||||
|
@ -352,7 +364,7 @@ test('out-of-date clients will receive incompatibility errors', () => {
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 0,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV2.serialize(),
|
||||
})
|
||||
|
||||
|
@ -363,6 +375,38 @@ test('out-of-date clients will receive incompatibility errors', () => {
|
|||
})
|
||||
|
||||
test('clients using an out-of-date protocol will receive compatibility errors', () => {
|
||||
const actualVersion = getTlsyncProtocolVersion()
|
||||
mockGetTlsyncProtocolVersion.mockReturnValue(actualVersion + 1)
|
||||
try {
|
||||
const v2server = new TestServer(schemaV2)
|
||||
|
||||
const id = 'test_upgrade_v3'
|
||||
const socket = mockSocket()
|
||||
|
||||
v2server.room.handleNewSession(id, socket)
|
||||
v2server.room.handleMessage(id, {
|
||||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 0,
|
||||
protocolVersion: actualVersion,
|
||||
schema: schemaV2.serialize(),
|
||||
})
|
||||
|
||||
expect(socket.sendMessage).toHaveBeenCalledWith({
|
||||
type: 'incompatibility_error',
|
||||
reason: TLIncompatibilityReason.ClientTooOld,
|
||||
})
|
||||
} finally {
|
||||
mockGetTlsyncProtocolVersion.mockReset()
|
||||
mockGetTlsyncProtocolVersion.mockImplementation(actualProtocol.getTlsyncProtocolVersion)
|
||||
}
|
||||
})
|
||||
|
||||
// this can be deleted when the protocol gets to v7
|
||||
test('v5 special case should allow connections', () => {
|
||||
const actualVersion = getTlsyncProtocolVersion()
|
||||
if (actualVersion > 6) return
|
||||
|
||||
const v2server = new TestServer(schemaV2)
|
||||
|
||||
const id = 'test_upgrade_v3'
|
||||
|
@ -373,13 +417,23 @@ test('clients using an out-of-date protocol will receive compatibility errors',
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 0,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION - 2,
|
||||
protocolVersion: 5,
|
||||
schema: schemaV2.serialize(),
|
||||
})
|
||||
|
||||
expect(socket.sendMessage).toHaveBeenCalledWith({
|
||||
type: 'incompatibility_error',
|
||||
reason: TLIncompatibilityReason.ClientTooOld,
|
||||
connectRequestId: 'test',
|
||||
diff: {},
|
||||
hydrationType: 'wipe_all',
|
||||
protocolVersion: 6,
|
||||
schema: {
|
||||
schemaVersion: 2,
|
||||
sequences: {
|
||||
'com.tldraw.user': 1,
|
||||
},
|
||||
},
|
||||
serverClock: 1,
|
||||
type: 'connect',
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -394,7 +448,7 @@ test('clients using a too-new protocol will receive compatibility errors', () =>
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 0,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION + 1,
|
||||
protocolVersion: getTlsyncProtocolVersion() + 1,
|
||||
schema: schemaV2.serialize(),
|
||||
})
|
||||
|
||||
|
@ -436,7 +490,7 @@ test('when the client is too new it cannot connect', () => {
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 10,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV2.serialize(),
|
||||
})
|
||||
|
||||
|
@ -496,7 +550,7 @@ describe('when the client is too old', () => {
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 10,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV1.serialize(),
|
||||
})
|
||||
|
||||
|
@ -505,7 +559,7 @@ describe('when the client is too old', () => {
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 10,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV2.serialize(),
|
||||
})
|
||||
|
||||
|
@ -514,7 +568,7 @@ describe('when the client is too old', () => {
|
|||
connectRequestId: 'test',
|
||||
hydrationType: 'wipe_presence',
|
||||
diff: {},
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV2.serialize(),
|
||||
serverClock: 10,
|
||||
} satisfies TLSocketServerSentEvent<RV2>)
|
||||
|
@ -524,7 +578,7 @@ describe('when the client is too old', () => {
|
|||
connectRequestId: 'test',
|
||||
hydrationType: 'wipe_presence',
|
||||
diff: {},
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV2.serialize(),
|
||||
serverClock: 10,
|
||||
} satisfies TLSocketServerSentEvent<RV2>)
|
||||
|
@ -643,7 +697,7 @@ describe('when the client is the same version', () => {
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 10,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: JSON.parse(JSON.stringify(schemaV2.serialize())),
|
||||
})
|
||||
|
||||
|
@ -652,7 +706,7 @@ describe('when the client is the same version', () => {
|
|||
type: 'connect',
|
||||
connectRequestId: 'test',
|
||||
lastServerClock: 10,
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: JSON.parse(JSON.stringify(schemaV2.serialize())),
|
||||
})
|
||||
|
||||
|
@ -661,7 +715,7 @@ describe('when the client is the same version', () => {
|
|||
connectRequestId: 'test',
|
||||
hydrationType: 'wipe_presence',
|
||||
diff: {},
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV2.serialize(),
|
||||
serverClock: 10,
|
||||
} satisfies TLSocketServerSentEvent<RV2>)
|
||||
|
@ -671,7 +725,7 @@ describe('when the client is the same version', () => {
|
|||
connectRequestId: 'test',
|
||||
hydrationType: 'wipe_presence',
|
||||
diff: {},
|
||||
protocolVersion: TLSYNC_PROTOCOL_VERSION,
|
||||
protocolVersion: getTlsyncProtocolVersion(),
|
||||
schema: schemaV2.serialize(),
|
||||
serverClock: 10,
|
||||
} satisfies TLSocketServerSentEvent<RV2>)
|
||||
|
|
Loading…
Reference in a new issue