From 5ddc2719443d52b374b2a6b14c2b0d530aba9fa9 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Thu, 18 Jun 2026 16:46:03 +0530 Subject: [PATCH] Add ObjectData json type and UNKNOWN enum sentinels to objects spec Extend the LiveObjects wire types in features.md: - OD2g: add a `json` value field to `ObjectData`, holding a JSON object or array leaf value, sent/received as a JSON-encoded string over the JSON protocol. Update OD2c-OD2f so `json` is listed among the mutually-exclusive value fields, and add the field to the IDL. - OD3a / OD3g: include `json` in the `ObjectData` size calculation; its size is the byte length of its JSON-encoded string representation. This matches both reference implementations (ably-js _getObjectDataSize and ably-java ObjectData.size()). - OOP2a / OMP2a: add a client-side `UNKNOWN` sentinel to the `ObjectOperationAction` and `ObjectsMapSemantics` enums. It has no wire value and is never encoded or sent; decoding an unrecognised action or semantics value yields `UNKNOWN` instead of failing, giving clients a defined way to detect and safely ignore operations they do not understand (e.g. introduced by a newer protocol version). Reflected in the IDL. Co-Authored-By: Claude Opus 4.8 (1M context) --- specifications/features.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/specifications/features.md b/specifications/features.md index c96fffb2a..901bdc906 100644 --- a/specifications/features.md +++ b/specifications/features.md @@ -1311,6 +1311,7 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info - `(OOP1)` An `ObjectOperation` describes an operation to be applied to an object on a channel - `(OOP2)` `ObjectOperationAction` enum has the following values in order from zero: `MAP_CREATE`, `MAP_SET`, `MAP_REMOVE`, `COUNTER_CREATE`, `COUNTER_INC`, `OBJECT_DELETE`, `MAP_CLEAR` + - `(OOP2a)` The enum additionally has an `UNKNOWN` value, which has no wire representation. When decoding, an `action` that does not map to any of the wire-ordered members above must be decoded as `UNKNOWN` rather than failing. The client library must never encode or send `UNKNOWN`, and must ignore (not apply) any `ObjectOperation` whose `action` is `UNKNOWN` - `(OOP3)` The attributes available in an `ObjectOperation` are: - `(OOP3a)` `action` `ObjectOperationAction` enum - defines the operation to be applied to the object - `(OOP3b)` `objectId` string - the object ID of the object on a channel to which the operation should be applied @@ -1474,6 +1475,7 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info - `(OMP1)` An `ObjectsMap` object represents a map of key-value pairs - `(OMP2)` `ObjectsMapSemantics` enum has the following values in order from zero: `LWW` + - `(OMP2a)` The enum additionally has an `UNKNOWN` value, which has no wire representation. When decoding, a `semantics` value that does not map to any of the wire-ordered members above must be decoded as `UNKNOWN` rather than failing. The client library must never encode or send `UNKNOWN` - `(OMP3)` The attributes available in an `ObjectsMap` are: - `(OMP3a)` `semantics` `ObjectsMapSemantics` enum - the conflict-resolution semantics used by the map object - `(OMP3b)` `entries` `Dict` - the map entries, indexed by key @@ -1512,16 +1514,18 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info - `(OD2)` The attributes available in an `ObjectData` are: - `(OD2a)` `objectId` string - a reference to another object - `(OD2b)` `encoding` string - may be set by the client library to indicate that value in `string` field have an encoding - - `(OD2c)` `boolean` boolean - a primitive boolean leaf value in the object graph. Only one of the value fields - `boolean`, `bytes`, `number` or `string` - must be set at a time - - `(OD2d)` `bytes` binary \| string - a primitive binary leaf value in the object graph. It is sent to and received from the server as a Base64-encoded string when using the JSON protocol. Only one of the value fields - `boolean`, `bytes`, `number` or `string` - must be set at a time - - `(OD2e)` `number` number - a primitive number leaf value in the object graph. Only one of the value fields - `boolean`, `bytes`, `number` or `string` - must be set at a time - - `(OD2f)` `string` string - a primitive string leaf value in the object graph. Only one of the value fields - `boolean`, `bytes`, `number` or `string` - must be set at a time + - `(OD2c)` `boolean` boolean - a primitive boolean leaf value in the object graph. Only one of the value fields - `boolean`, `bytes`, `number`, `string` or `json` - must be set at a time + - `(OD2d)` `bytes` binary \| string - a primitive binary leaf value in the object graph. It is sent to and received from the server as a Base64-encoded string when using the JSON protocol. Only one of the value fields - `boolean`, `bytes`, `number`, `string` or `json` - must be set at a time + - `(OD2e)` `number` number - a primitive number leaf value in the object graph. Only one of the value fields - `boolean`, `bytes`, `number`, `string` or `json` - must be set at a time + - `(OD2f)` `string` string - a primitive string leaf value in the object graph. Only one of the value fields - `boolean`, `bytes`, `number`, `string` or `json` - must be set at a time + - `(OD2g)` `json` JsonObject \| JsonArray - a primitive JSON leaf value (an object or array) in the object graph. It is sent to and received from the server as a JSON-encoded string when using the JSON protocol. Only one of the value fields - `boolean`, `bytes`, `number`, `string` or `json` - must be set at a time - `(OD3)` The size of the `ObjectData` is calculated as follows: - - `(OD3a)` The size is the sum of the sizes of the `boolean`, `bytes`, `number`, and `string` properties + - `(OD3a)` The size is the sum of the sizes of the `boolean`, `bytes`, `number`, `string`, and `json` properties - `(OD3b)` If set, the size of a `boolean` property is 1 - `(OD3c)` If set, the size of a `bytes` property is its size in bytes (of the actual binary, not the base64 representation, regardless of whether the binary protocol is in use) - `(OD3d)` If set, the size of a `number` property is 8 - `(OD3e)` If set, the size of a `string` property is its length + - `(OD3g)` If set, the size of a `json` property is the byte length of its JSON-encoded string representation - `(OD3f)` The size of a `null` or omitted property is zero - `(OD4)` `ObjectData` encoding: - `(OD4a)` Payloads must be booleans, binary, numbers, strings, or JSON-encodable objects or arrays. Any other data type must not be permitted and result in an error with code 40013 @@ -2488,9 +2492,11 @@ Each type, method, and attribute is labelled with the name of one or more clause COUNTER_INC // OOP2 OBJECT_DELETE // OOP2 MAP_CLEAR // OOP2 + UNKNOWN // OOP2a, client-side sentinel, never sent/received over the wire enum ObjectsMapSemantics: // OMP2, internal LWW // OMP2 + UNKNOWN // OMP2a, client-side sentinel, never sent/received over the wire enum AnnotationAction: // TAN2b ANNOTATION_CREATE @@ -2628,6 +2634,7 @@ Each type, method, and attribute is labelled with the name of one or more clause bytes: Binary? | String? // OD2d number: Number? // OD2e string: String? // OD2f + json: String? // OD2g class Annotation // TAN* +fromEncoded(JsonObject, ChannelOptions?) -> Annotation // TAN3