Skip to content

Commit b30a71a

Browse files
Merge pull request #485 from ably/integration/liveobjects-path-based-api-ditch-merge-commits
LiveObjects: merge path-based API into `main`
2 parents b5930f2 + 7ba0b8f commit b30a71a

3 files changed

Lines changed: 717 additions & 218 deletions

File tree

CONTRIBUTING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ Historically, before the above guidance was established - in particular around _
4444
This left us open to the problem that client library references to spec items could end up semantically invalid if that spec point was re-used later.
4545
For example, if `XXX1a` and `XXX1c` exist but `XXX1b` doesn’t because it was removed in the past (prior to this guidance being established), then we should introduce `XXX1d` for the new spec item rather than re-using `XXX1b`.
4646

47+
## Public-API namespacing for name clashes
48+
49+
Most spec types are public API by default (the IDL marks the exceptions with `internal`). When a public-API type would have the same natural name as an existing internal/wire concept, the first preference is to rename the internal concept so the public type can take the unqualified name. Where no good rename exists for the internal concept, or where renaming it would cause excessive churn or inconsistency across the spec, the spec instead qualifies the public type with a `PublicAPI::` namespace prefix (e.g. `PublicAPI::ObjectMessage`).
50+
51+
This is purely a spec-side disambiguation: SDKs should expose the type to users under its unqualified name (here, `ObjectMessage`). Where an SDK's language uses a single flat namespace and cannot have two types with that name, the canonical/wire concept may be renamed internally (e.g. `WireObjectMessage`) to free up the public name.
52+
53+
The `PublicAPI::` prefix is only introduced when there is an actual clash; the bare name remains the canonical reference everywhere else.
54+
4755
## SDK API docstrings
4856

4957
The `api-docstrings.md` file is a set of language-agnostic reference API commentaries for SDK developers to use when adding docstring comments to Ably SDKs. For new fields, this file should be modified in the same PR that makes the spec changes for those fields.

specifications/features.md

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -377,15 +377,15 @@ Support for the deprecated client options `environment`, `restHost`, `realtimeHo
377377
- `(PC2)` No generic plugin interface is specified, and therefore there is no common API exposed by all plugins. However, for type-safety, the opaque interface `Plugin` should be used in strongly-typed languages as the type of the `ClientOptions.plugins` collection as per [TO3o](#TO3o).
378378
- `(PC3)` A plugin provided with the `PluginType` enum key value of `vcdiff` should be capable of decoding "vcdiff"-encoded messages. It must implement the `VCDiffDecoder` interface and the client library must be able to use it by casting it to this interface.
379379
- `(PC3a)` The base argument of the `VCDiffDecoder.decode` method should receive the stored base payload of the last message on a channel as specified by [RTL19](#RTL19). If the base payload is a string it should be encoded to binary using UTF-8 before being passed as base argument of the `VCDiffDecoder.decode` method.
380-
- `(PC5)` A plugin provided with the `PluginType` enum key value of `Objects` should provide the [RealtimeObjects](../objects-features#RTO1) feature functionality for realtime channels ([RTL27](#RTL27)). The plugin object itself is not expected to provide a public API. The type of the plugin object, and how it enables the Objects feature for a realtime channel, are left for individual implementations to decide.
380+
- `(PC5)` A plugin provided with the `PluginType` enum key value of `LiveObjects` should provide the [RealtimeObject](../objects-features#RTO23) feature functionality for realtime channels ([RTL27](#RTL27)). The plugin object itself is not expected to provide a public API. The type of the plugin object, and how it enables the Objects feature for a realtime channel, are left for individual implementations to decide.
381381
- `(PC4)` A client library is allowed to accept plugins other than those specified in this specification, through the use of additional `ClientOptions.plugins` keys defined by that library. The library is responsible for defining the interface of these plugins, and for making sure that these keys do not clash with the keys defined in this specification.
382382

383383
### PluginType {#plugin-type}
384384

385385
- `(PT1)` `PluginType` is an enum describing the different types of plugins that the library supports. See the `ClientOptions#plugins` property ([TO3o](#TO3o)).
386386
- `(PT2)` `PluginType` takes one of the following values:
387387
- `(PT2a)` `vcdiff` -- see [PC3](#PC3).
388-
- `(PT2b)` `Objects` -- see [PC5](#PC5).
388+
- `(PT2b)` `LiveObjects` -- see [PC5](#PC5).
389389

390390
### VCDiffDecoder {#vcdiff-decoder}
391391

@@ -673,7 +673,7 @@ The threading and/or asynchronous model for each realtime library will vary by l
673673
### RealtimeChannel {#realtime-channel}
674674

675675
- `(RTL23)` `RealtimeChannel#name` attribute is a string containing the channel's name
676-
- `(RTL1)` As soon as a `RealtimeChannel` becomes attached, all incoming messages, presence messages and object messages (where 'incoming' is defined as 'received from Ably over the realtime transport') are processed and emitted where applicable. `PRESENCE` and `SYNC` messages are passed to the `RealtimePresence` object ensuring it maintains a map of current members on a channel in realtime. `OBJECT` and `OBJECT_SYNC` messages are passed to the `RealtimeObjects` object ensuring it maintains an up-to-date representation of objects on a channel in realtime
676+
- `(RTL1)` As soon as a `RealtimeChannel` becomes attached, all incoming messages, presence messages and object messages (where 'incoming' is defined as 'received from Ably over the realtime transport') are processed and emitted where applicable. `PRESENCE` and `SYNC` messages are passed to the `RealtimePresence` object ensuring it maintains a map of current members on a channel in realtime. `OBJECT` and `OBJECT_SYNC` messages are passed to the `RealtimeObject` object ensuring it maintains an up-to-date representation of objects on a channel in realtime
677677
- `(RTL2)` The `RealtimeChannel` implements `EventEmitter` and emits `ChannelEvent` events, where a `ChannelEvent` is either a `ChannelState` or `UPDATE`, and a `ChannelState` is either `INITIALIZED`, `ATTACHING`, `ATTACHED`, `DETACHING`, `DETACHED`, `SUSPENDED` and `FAILED`
678678
- `(RTL2a)` It emits a `ChannelState` `ChannelEvent` for every channel state change
679679
- `(RTL2g)` It emits an `UPDATE` `ChannelEvent` for changes to channel conditions for which the `ChannelState` (e.g. `ATTACHED`) does not change, unless explicitly prevented by a more specific condition (see [RTL12](#RTL12)). (The library must never emit a `ChannelState` `ChannelEvent` for a state equal to the previous state)
@@ -767,9 +767,9 @@ The threading and/or asynchronous model for each realtime library will vary by l
767767
- `(RTL8b)` Unsubscribe with a name argument and a listener argument unsubscribes the provided listener if previously subscribed with a name-specific subscription
768768
- `(RTL9)` `RealtimeChannel#presence` attribute:
769769
- `(RTL9a)` Returns the `RealtimePresence` object for this channel
770-
- `(RTL27)` `RealtimeChannel#objects` attribute:
771-
- `(RTL27a)` Returns the `RealtimeObjects` object for this channel [RTO1](../objects-features#RTO1)
772-
- `(RTL27b)` It is a programmer error to access this property without first providing the `Objects` plugin ([PC5](#PC5)) in the client options. This programmer error should be handled in an idiomatic fashion; if this means accessing the property should throw an error, then the error should be an `ErrorInfo` with `statusCode` 400 and `code` 40019.
770+
- `(RTL27)` `RealtimeChannel#object` attribute:
771+
- `(RTL27a)` Returns the `RealtimeObject` object for this channel [RTO23](../objects-features#RTO23)
772+
- `(RTL27b)` It is a programmer error to access this property without first providing the `LiveObjects` plugin ([PC5](#PC5)) in the client options. This programmer error should be handled in an idiomatic fashion; if this means accessing the property should throw an error, then the error should be an `ErrorInfo` with `statusCode` 400 and `code` 40019.
773773
- `(RTL10)` `RealtimeChannel#history` function:
774774
- `(RTL10a)` Supports all the same params as `RestChannel#history`
775775
- `(RTL10b)` Additionally supports the param `untilAttach`, which if true, will only retrieve messages prior to the moment that the channel was attached or emitted an `UPDATE` indicating loss of continuity. This bound is specified by passing the querystring param `fromSerial` with the `RealtimeChannel#properties.attachSerial` assigned to the channel in the `ATTACHED` `ProtocolMessage` (see [RTL15a](#RTL15a)). If the `untilAttach` param is specified when the channel is not attached, it results in an error
@@ -937,9 +937,9 @@ The threading and/or asynchronous model for each realtime library will vary by l
937937
- `(RTP15e)` Implicitly attaches the `RealtimeChannel` if the channel is in the `INITIALIZED` state. However, if the channel is in or enters the `DETACHED` or `FAILED` state before the operation succeeds, it will result in an error
938938
- `(RTP15f)` If the client is identified and has a valid `clientId`, and the `clientId` argument does not match the client's `clientId`, then it should indicate an error. The connection and channel remain available for further operations
939939

940-
### RealtimeObjects {#realtime-objects}
940+
### RealtimeObject {#realtime-objects}
941941

942-
Reserved for `RealtimeObjects` feature specification, see [objects-features](../objects-features). Reserved spec points: `RTO`, `RTLO`, `RTLC`, `RTLM`
942+
Reserved for `RealtimeObject` feature specification, see [objects-features](../objects-features). Reserved spec points: `RTO`, `RTLO`, `RTLC`, `RTLM`, `RTPO`, `RTINS`, `RTLCV`, `RTLMV`
943943

944944
### RealtimeAnnotations {#realtime-annotations}
945945

@@ -1333,13 +1333,13 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info
13331333
- `(OOP4g)` The size is the sum of the sizes of the map create, `mapSet`, `mapRemove`, counter create, and `counterInc` components
13341334
- `(OOP4h)` The size of the map create component is:
13351335
- `(OOP4h1)` If `mapCreate` is present, it is equal to the size of `mapCreate` calculated per [MCR3](#MCR3)
1336-
- `(OOP4h2)` Else if `mapCreateWithObjectId` is present, it is equal to the size of the `MapCreate` retained in [RTO11f18](objects-features#RTO11f18), calculated per [MCR3](#MCR3)
1336+
- `(OOP4h2)` Else if `mapCreateWithObjectId` is present, it is equal to the size of the `MapCreate` retained in [RTLMV4j5](objects-features#RTLMV4j5), calculated per [MCR3](#MCR3)
13371337
- `(OOP4h3)` Otherwise it is zero
13381338
- `(OOP4i)` The size of the `mapSet` property is calculated per [MST3](#MST3)
13391339
- `(OOP4j)` The size of the `mapRemove` property is calculated per [MRM3](#MRM3)
13401340
- `(OOP4k)` The size of the counter create component is:
13411341
- `(OOP4k1)` If `counterCreate` is present, it is equal to the size of `counterCreate` calculated per [CCR3](#CCR3)
1342-
- `(OOP4k2)` Else if `counterCreateWithObjectId` is present, it is equal to the size of the `CounterCreate` retained in [RTO12f16](objects-features#RTO12f16), calculated per [CCR3](#CCR3)
1342+
- `(OOP4k2)` Else if `counterCreateWithObjectId` is present, it is equal to the size of the `CounterCreate` retained in [RTLCV4g5](objects-features#RTLCV4g5), calculated per [CCR3](#CCR3)
13431343
- `(OOP4k3)` Otherwise it is zero
13441344
- `(OOP4l)` The size of the `counterInc` property is calculated per [CIN3](#CIN3)
13451345
- `(OOP4f)` The size of a `null` or omitted property is zero
@@ -1872,6 +1872,13 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info
18721872
- `(REX2b1)` Should be written in reverse domain name notation
18731873
- `(REX2b2)` Types beginning with `com.ably.` are reserved
18741874

1875+
#### Subscription
1876+
1877+
- `(SUB1)` A `Subscription` represents a registration for receiving events from a subscribe operation
1878+
- `(SUB2)` The `Subscription` object has the following method:
1879+
- `(SUB2a)` `unsubscribe` - deregisters the listener that was registered by the corresponding `subscribe` call. Once `unsubscribe` is called, the listener must not be called for any subsequent events
1880+
- `(SUB2b)` Calling `unsubscribe` more than once is a no-op
1881+
18751882
### Option types {#options}
18761883

18771884
#### ClientOptions
@@ -2260,7 +2267,7 @@ Each type, method, and attribute is labelled with the name of one or more clause
22602267
state: ChannelState // RTL2b
22612268
whenState(ChannelState, (ChannelStateChange?) ->) // RTL25
22622269
presence: RealtimePresence // RTL9
2263-
objects: RealtimeObjects // RTL27
2270+
object: RealtimeObject // RTL27
22642271
properties: ChannelProperties // RTL15
22652272
// Only on platforms that support receiving push notifications:
22662273
push: PushChannel // RSH7
@@ -2840,7 +2847,7 @@ Each type, method, and attribute is labelled with the name of one or more clause
28402847

28412848
enum PluginType // PT*
28422849
"vcdiff" // PT2a
2843-
"Objects" // PT2b
2850+
"LiveObjects" // PT2b
28442851

28452852
class VCDiffDecoder // VD*
28462853
decode([byte] delta, [byte] base) -> [byte] // VD2a, PC3a
@@ -2926,6 +2933,9 @@ Each type, method, and attribute is labelled with the name of one or more clause
29262933
description: string? // TM2s4
29272934
metadata: Dict<string, string>? //TM2s5
29282935

2936+
interface Subscription: // SUB*
2937+
unsubscribe() // SUB2a
2938+
29292939
## Old specs
29302940

29312941
Use the version navigation to view older versions. References to diffs for each version are maintained below:

0 commit comments

Comments
 (0)