diff --git a/packages/zero-cache/src/workers/connection.ts b/packages/zero-cache/src/workers/connection.ts index 510e7f726..8f85bbfa7 100644 --- a/packages/zero-cache/src/workers/connection.ts +++ b/packages/zero-cache/src/workers/connection.ts @@ -16,7 +16,10 @@ import { type PongMessage, upstreamSchema, } from '../../../zero-protocol/src/mod.js'; -import {PROTOCOL_VERSION} from '../../../zero-protocol/src/protocol-version.js'; +import { + MIN_SERVER_SUPPORTED_PROTOCOL_VERSION, + PROTOCOL_VERSION, +} from '../../../zero-protocol/src/protocol-version.js'; import type {ConnectParams} from '../services/dispatcher/connect-params.js'; import type {Mutagen} from '../services/mutagen/mutagen.js'; import type { @@ -102,14 +105,16 @@ export class Connection { */ init() { if ( - this.#protocolVersion !== PROTOCOL_VERSION && - this.#protocolVersion !== PROTOCOL_VERSION - 1 + this.#protocolVersion > PROTOCOL_VERSION || + this.#protocolVersion < MIN_SERVER_SUPPORTED_PROTOCOL_VERSION ) { this.#closeWithError({ kind: ErrorKind.VersionNotSupported, - message: `server supports v${ - PROTOCOL_VERSION - 1 - } and v${PROTOCOL_VERSION} protocols`, + message: `server is at sync protocol v${PROTOCOL_VERSION} and does not support v${ + this.#protocolVersion + }. The ${ + this.#protocolVersion > PROTOCOL_VERSION ? 'server' : 'client' + } must be updated to a newer release.`, }); } else { const connectedMessage: ConnectedMessage = [ diff --git a/packages/zero-protocol/src/protocol-version.ts b/packages/zero-protocol/src/protocol-version.ts index 407219b6f..2af2e2369 100644 --- a/packages/zero-protocol/src/protocol-version.ts +++ b/packages/zero-protocol/src/protocol-version.ts @@ -1,4 +1,8 @@ +import {assert} from '../../shared/src/asserts.js'; + /** + * The current `PROTOCOL_VERSION` of the code. + * * The `PROTOCOL_VERSION` encompasses both the wire-protocol of the `/sync/...` * connection between the browser and `zero-cache`, as well as the format of * the `AST` objects stored in both components (i.e. IDB and CVR). @@ -7,13 +11,18 @@ * accompanied by an increment of the `PROTOCOL_VERSION` and a new major * release. The server (`zero-cache`) must be deployed before clients start * running the new code. - * - * The contract for backwards compatibility is that a `zero-cache` supports - * its current `PROTOCOL_VERSION` and the previous one (i.e. - * `PROTOCOL_VERSION - 1`, which is necessary to support old clients when - * the server is rolled out). This corresponds to supporting clients running - * the current release and the previous (major) release. Any client connections - * from earlier protocol versions are closed with a `VersionNotSupported` - * error. */ export const PROTOCOL_VERSION = 3; + +/** + * The minimum protocol version supported by the server. The contract for + * backwards compatibility is that a `zero-cache` supports the current + * `PROTOCOL_VERSION` and at least the previous one (i.e. `PROTOCOL_VERSION - 1`) + * if not earlier ones as well. This corresponds to supporting clients running + * the current release and the previous (major) release. Any client connections + * from protocol versions before `MIN_SERVER_SUPPORTED_PROTOCOL_VERSION` are + * closed with a `VersionNotSupported` error. + */ +export const MIN_SERVER_SUPPORTED_PROTOCOL_VERSION = 2; + +assert(MIN_SERVER_SUPPORTED_PROTOCOL_VERSION < PROTOCOL_VERSION);