From 479e9264a8c0ef00ed34e4ba2f748df8c2fc4c1b Mon Sep 17 00:00:00 2001 From: Steven Lindsay Date: Wed, 9 Oct 2024 13:10:40 +0100 Subject: [PATCH] materialisation: Add new message fields. Added MessageAction enum to represent different message actions, and mapped action numbers to these enums. Added `serial` to the message, this is the unique serial (including index) of the message. Added the following fields related to message annotations - `refSerial` - `refType` Added the following fields related to message edits/deletes - `operation` - `editedAt` - `deletedAt` --- ably.d.ts | 182 +++++++++++++++++++++++++ src/common/lib/types/defaultmessage.ts | 3 +- src/common/lib/types/message.ts | 66 ++++++++- 3 files changed, 249 insertions(+), 2 deletions(-) diff --git a/ably.d.ts b/ably.d.ts index b8e85c6a4..ffcc1b3b5 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -1561,6 +1561,7 @@ export declare interface EventEmitter { * @param callback - The event listener. */ on(event: EventType, callback: CallbackType): void; + /** * Registers the provided listener for the specified events. If `on()` is called more than once with the same listener and event, the listener is added multiple times to its listener registry. Therefore, as an example, assuming the same listener is registered twice using `on()`, and an event is emitted once, the listener would be invoked twice. * @@ -1568,12 +1569,14 @@ export declare interface EventEmitter { * @param callback - The event listener. */ on(events: EventType[], callback: CallbackType): void; + /** * Registers the provided listener all events. If `on()` is called more than once with the same listener and event, the listener is added multiple times to its listener registry. Therefore, as an example, assuming the same listener is registered twice using `on()`, and an event is emitted once, the listener would be invoked twice. * * @param callback - The event listener. */ on(callback: CallbackType): void; + /** * Registers the provided listener for the first occurrence of a single named event specified as the `Event` argument. If `once` is called more than once with the same listener, the listener is added multiple times to its listener registry. Therefore, as an example, assuming the same listener is registered twice using `once`, and an event is emitted once, the listener would be invoked twice. However, all subsequent events emitted would not invoke the listener as `once` ensures that each registration is only invoked once. * @@ -1581,12 +1584,14 @@ export declare interface EventEmitter { * @param callback - The event listener. */ once(event: EventType, callback: CallbackType): void; + /** * Registers the provided listener for the first event that is emitted. If `once()` is called more than once with the same listener, the listener is added multiple times to its listener registry. Therefore, as an example, assuming the same listener is registered twice using `once()`, and an event is emitted once, the listener would be invoked twice. However, all subsequent events emitted would not invoke the listener as `once()` ensures that each registration is only invoked once. * * @param callback - The event listener. */ once(callback: CallbackType): void; + /** * Returns a promise which resolves upon the first occurrence of a single named event specified as the `Event` argument. * @@ -1594,12 +1599,14 @@ export declare interface EventEmitter { * @returns A promise which resolves upon the first occurrence of the named event. */ once(event: EventType): Promise; + /** * Returns a promise which resolves upon the first occurrence of an event. * * @returns A promise which resolves upon the first occurrence of an event. */ once(): Promise; + /** * Removes all registrations that match both the specified listener and the specified event. * @@ -1607,16 +1614,19 @@ export declare interface EventEmitter { * @param callback - The event listener. */ off(event: EventType, callback: CallbackType): void; + /** * Deregisters the specified listener. Removes all registrations matching the given listener, regardless of whether they are associated with an event or not. * * @param callback - The event listener. */ off(callback: CallbackType): void; + /** * Deregisters all registrations, for all events and listeners. */ off(): void; + /** * Returns the listeners for a specified `EventType`. * @@ -1638,6 +1648,7 @@ export declare interface RestClient { * A {@link Channels} object. */ channels: Channels; + /** * Makes a REST request to a provided path. This is provided as a convenience for developers who wish to use REST API functionality that is either not documented or is not yet included in the public API, without having to directly handle features such as authentication, paging, fallback hosts, MsgPack and JSON support. * @@ -1657,6 +1668,7 @@ export declare interface RestClient { body?: any[] | any, headers?: any, ): Promise>; + /** * Queries the REST `/stats` API and retrieves your application's usage statistics. Returns a {@link PaginatedResult} object, containing an array of {@link Stats} objects. See the [Stats docs](https://ably.com/docs/general/statistics). * @@ -1664,6 +1676,7 @@ export declare interface RestClient { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link Stats} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ stats(params?: StatsParams): Promise>; + /** * Retrieves the time from the Ably service as milliseconds since the Unix epoch. Clients that do not have access to a sufficiently well maintained time source and wish to issue Ably {@link TokenRequest | `TokenRequest`s} with a more accurate timestamp should use the {@link ClientOptions.queryTime} property instead of this method. * @@ -1678,6 +1691,7 @@ export declare interface RestClient { * @returns A promise which, upon success, will be fulfilled with a {@link BatchResult} object containing information about the result of the batch publish for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPublish(spec: BatchPublishSpec): Promise>; + /** * Publishes one or more {@link BatchPublishSpec} objects to one or more channels, up to a maximum of 100 channels. * @@ -1687,6 +1701,7 @@ export declare interface RestClient { batchPublish( specs: BatchPublishSpec[], ): Promise[]>; + /** * Retrieves the presence state for one or more channels, up to a maximum of 100 channels. Presence state includes the `clientId` of members and their current {@link PresenceAction}. * @@ -1694,6 +1709,7 @@ export declare interface RestClient { * @returns A promise which, upon success, will be fulfilled with a {@link BatchResult} object containing information about the result of the batch presence request for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPresence(channels: string[]): Promise[]>; + /** * A {@link Push} object. */ @@ -1708,10 +1724,12 @@ export declare interface RealtimeClient { * A client ID, used for identifying this client when publishing messages or for presence purposes. The `clientId` can be any non-empty string, except it cannot contain a `*`. This option is primarily intended to be used in situations where the library is instantiated with a key. A `clientId` may also be implicit in a token used to instantiate the library; an error will be raised if a `clientId` specified here conflicts with the `clientId` implicit in the token. */ clientId: string; + /** * Calls {@link Connection.close | `connection.close()`} and causes the connection to close, entering the closing state. Once closed, the library will not attempt to re-establish the connection without an explicit call to {@link Connection.connect | `connect()`}. */ close(): void; + /** * Calls {@link Connection.connect | `connection.connect()`} and causes the connection to open, entering the connecting state. Explicitly calling `connect()` is unnecessary unless the {@link ClientOptions.autoConnect} property is disabled. */ @@ -1729,6 +1747,7 @@ export declare interface RealtimeClient { * A {@link Connection} object. */ connection: Connection; + /** * Makes a REST request to a provided path. This is provided as a convenience for developers who wish to use REST API functionality that is either not documented or is not yet included in the public API, without having to directly handle features such as authentication, paging, fallback hosts, MsgPack and JSON support. * @@ -1748,6 +1767,7 @@ export declare interface RealtimeClient { body?: any[] | any, headers?: any, ): Promise>; + /** * Queries the REST `/stats` API and retrieves your application's usage statistics. Returns a {@link PaginatedResult} object, containing an array of {@link Stats} objects. See the [Stats docs](https://ably.com/docs/general/statistics). * @@ -1755,12 +1775,14 @@ export declare interface RealtimeClient { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link Stats} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ stats(params?: StatsParams): Promise>; + /** * Retrieves the time from the Ably service as milliseconds since the Unix epoch. Clients that do not have access to a sufficiently well maintained time source and wish to issue Ably {@link TokenRequest | `TokenRequest`s} with a more accurate timestamp should use the {@link ClientOptions.queryTime} property instead of this method. * * @returns A promise which, upon success, will be fulfilled with the time as milliseconds since the Unix epoch. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ time(): Promise; + /** * Publishes a {@link BatchPublishSpec} object to one or more channels, up to a maximum of 100 channels. * @@ -1768,6 +1790,7 @@ export declare interface RealtimeClient { * @returns A promise which, upon success, will be fulfilled with a {@link BatchResult} object containing information about the result of the batch publish for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPublish(spec: BatchPublishSpec): Promise>; + /** * Publishes one or more {@link BatchPublishSpec} objects to one or more channels, up to a maximum of 100 channels. * @@ -1777,6 +1800,7 @@ export declare interface RealtimeClient { batchPublish( specs: BatchPublishSpec[], ): Promise[]>; + /** * Retrieves the presence state for one or more channels, up to a maximum of 100 channels. Presence state includes the `clientId` of members and their current {@link PresenceAction}. * @@ -1784,6 +1808,7 @@ export declare interface RealtimeClient { * @returns A promise which, upon success, will be fulfilled with a {@link BatchResult} object containing information about the result of the batch presence request for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPresence(channels: string[]): Promise[]>; + /** * A {@link Push} object. */ @@ -1807,6 +1832,7 @@ export declare interface Auth { * @returns A promise which, upon success, will be fulfilled with a {@link TokenDetails} object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ authorize(tokenParams?: TokenParams, authOptions?: AuthOptions): Promise; + /** * Creates and signs an Ably {@link TokenRequest} based on the specified (or if none specified, the client library stored) {@link TokenParams} and {@link AuthOptions}. Note this can only be used when the API `key` value is available locally. Otherwise, the Ably {@link TokenRequest} must be obtained from the key owner. Use this to generate an Ably {@link TokenRequest} in order to implement an Ably Token request callback for use by other clients. Both {@link TokenParams} and {@link AuthOptions} are optional. When omitted or `null`, the default token parameters and authentication options for the client library are used, as specified in the {@link ClientOptions} when the client library was instantiated, or later updated with an explicit `authorize` request. Values passed in are used instead of, rather than being merged with, the default values. To understand why an Ably {@link TokenRequest} may be issued to clients in favor of a token, see [Token Authentication explained](https://ably.com/docs/core-features/authentication/#token-authentication). * @@ -1815,6 +1841,7 @@ export declare interface Auth { * @returns A promise which, upon success, will be fulfilled with a {@link TokenRequest} object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ createTokenRequest(tokenParams?: TokenParams, authOptions?: AuthOptions): Promise; + /** * Calls the `requestToken` REST API endpoint to obtain an Ably Token according to the specified {@link TokenParams} and {@link AuthOptions}. Both {@link TokenParams} and {@link AuthOptions} are optional. When omitted or `null`, the default token parameters and authentication options for the client library are used, as specified in the {@link ClientOptions} when the client library was instantiated, or later updated with an explicit `authorize` request. Values passed in are used instead of, rather than being merged with, the default values. To understand why an Ably {@link TokenRequest} may be issued to clients in favor of a token, see [Token Authentication explained](https://ably.com/docs/core-features/authentication/#token-authentication). * @@ -1823,6 +1850,7 @@ export declare interface Auth { * @returns A promise which, upon success, will be fulfilled with a {@link TokenDetails} object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ requestToken(TokenParams?: TokenParams, authOptions?: AuthOptions): Promise; + /** * Revokes the tokens specified by the provided array of {@link TokenRevocationTargetSpecifier}s. Only tokens issued by an API key that had revocable tokens enabled before the token was issued can be revoked. See the [token revocation docs](https://ably.com/docs/core-features/authentication#token-revocation) for more information. * @@ -1847,6 +1875,7 @@ export declare interface Presence { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link PresenceMessage} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ get(params?: RestPresenceParams): Promise>; + /** * Retrieves a {@link PaginatedResult} object, containing an array of historical {@link PresenceMessage} objects for the channel. If the channel is configured to persist messages, then presence messages can be retrieved from history for up to 72 hours in the past. If not, presence messages can only be retrieved from history for up to two minutes in the past. * @@ -1864,6 +1893,7 @@ export declare interface RealtimePresence { * Indicates whether the presence set synchronization between Ably and the clients on the channel has been completed. Set to `true` when the sync is complete. */ syncComplete: boolean; + /** * Deregisters a specific listener that is registered to receive {@link PresenceMessage} on the channel for a given {@link PresenceAction}. * @@ -1871,6 +1901,7 @@ export declare interface RealtimePresence { * @param listener - An event listener function. */ unsubscribe(presence: PresenceAction, listener: messageCallback): void; + /** * Deregisters a specific listener that is registered to receive {@link PresenceMessage} on the channel for a given array of {@link PresenceAction} objects. * @@ -1878,24 +1909,28 @@ export declare interface RealtimePresence { * @param listener - An event listener function. */ unsubscribe(presence: Array, listener: messageCallback): void; + /** * Deregisters any listener that is registered to receive {@link PresenceMessage} on the channel for a specific {@link PresenceAction} * * @param presence - A specific {@link PresenceAction} to deregister the listeners for. */ unsubscribe(presence: PresenceAction): void; + /** * Deregisters any listener that is registered to receive {@link PresenceMessage} on the channel for an array of {@link PresenceAction} objects * * @param presence - An array of {@link PresenceAction} objects to deregister the listeners for. */ unsubscribe(presence: Array): void; + /** * Deregisters a specific listener that is registered to receive {@link PresenceMessage} on the channel. * * @param listener - An event listener function. */ unsubscribe(listener: messageCallback): void; + /** * Deregisters all listeners currently receiving {@link PresenceMessage} for the channel. */ @@ -1908,6 +1943,7 @@ export declare interface RealtimePresence { * @returns A promise which, upon success, will be fulfilled with an array of {@link PresenceMessage} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ get(params?: RealtimePresenceParams): Promise; + /** * Retrieves a {@link PaginatedResult} object, containing an array of historical {@link PresenceMessage} objects for the channel. If the channel is configured to persist messages, then presence messages can be retrieved from history for up to 72 hours in the past. If not, presence messages can only be retrieved from history for up to two minutes in the past. * @@ -1915,6 +1951,7 @@ export declare interface RealtimePresence { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link PresenceMessage} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ history(params?: RealtimeHistoryParams): Promise>; + /** * Registers a listener that is called each time a {@link PresenceMessage} matching a given {@link PresenceAction}, or an action within an array of {@link PresenceAction | `PresenceAction`s}, is received on the channel, such as a new member entering the presence set. * @@ -1923,6 +1960,7 @@ export declare interface RealtimePresence { * @returns A promise which resolves upon success of the channel {@link RealtimeChannel.attach | `attach()`} operation and rejects with an {@link ErrorInfo} object upon its failure. */ subscribe(action: PresenceAction | Array, listener?: messageCallback): Promise; + /** * Registers a listener that is called each time a {@link PresenceMessage} is received on the channel, such as a new member entering the presence set. * @@ -1930,6 +1968,7 @@ export declare interface RealtimePresence { * @returns A promise which resolves upon success of the channel {@link RealtimeChannel.attach | `attach()`} operation and rejects with an {@link ErrorInfo} object upon its failure. */ subscribe(listener?: messageCallback): Promise; + /** * Enters the presence set for the channel, optionally passing a `data` payload. A `clientId` is required to be present on a channel. * @@ -1937,6 +1976,7 @@ export declare interface RealtimePresence { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ enter(data?: any): Promise; + /** * Updates the `data` payload for a presence member. If called before entering the presence set, this is treated as an {@link PresenceActions.ENTER} event. * @@ -1944,6 +1984,7 @@ export declare interface RealtimePresence { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ update(data?: any): Promise; + /** * Leaves the presence set for the channel. A client must have previously entered the presence set before they can leave it. * @@ -1951,6 +1992,7 @@ export declare interface RealtimePresence { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ leave(data?: any): Promise; + /** * Enters the presence set of the channel for a given `clientId`. Enables a single client to update presence on behalf of any number of clients using a single connection. The library must have been instantiated with an API key or a token bound to a wildcard `clientId`. * @@ -1959,6 +2001,7 @@ export declare interface RealtimePresence { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ enterClient(clientId: string, data?: any): Promise; + /** * Updates the `data` payload for a presence member using a given `clientId`. Enables a single client to update presence on behalf of any number of clients using a single connection. The library must have been instantiated with an API key or a token bound to a wildcard `clientId`. * @@ -1967,6 +2010,7 @@ export declare interface RealtimePresence { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ updateClient(clientId: string, data?: any): Promise; + /** * Leaves the presence set of the channel for a given `clientId`. Enables a single client to update presence on behalf of any number of clients using a single connection. The library must have been instantiated with an API key or a token bound to a wildcard `clientId`. * @@ -2027,6 +2071,7 @@ export declare interface Channel { * A {@link PushChannel} object. */ push: PushChannel; + /** * Retrieves a {@link PaginatedResult} object, containing an array of historical {@link InboundMessage} objects for the channel. If the channel is configured to persist messages, then messages can be retrieved from history for up to 72 hours in the past. If not, messages can only be retrieved from history for up to two minutes in the past. * @@ -2034,6 +2079,7 @@ export declare interface Channel { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link InboundMessage} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ history(params?: RestHistoryParams): Promise>; + /** * Publishes an array of messages to the channel. * @@ -2042,6 +2088,7 @@ export declare interface Channel { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ publish(messages: Message[], options?: PublishOptions): Promise; + /** * Publishes a message to the channel. * @@ -2050,6 +2097,7 @@ export declare interface Channel { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ publish(message: Message, options?: PublishOptions): Promise; + /** * Publishes a single message to the channel with the given event name and payload. * @@ -2059,6 +2107,7 @@ export declare interface Channel { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ publish(name: string, data: any, options?: PublishOptions): Promise; + /** * Retrieves a {@link ChannelDetails} object for the channel, which includes status and occupancy metrics. * @@ -2091,6 +2140,7 @@ export declare interface RealtimeChannel extends EventEmitter): void; + /** * Deregisters the given listener from all event names in the array. * @@ -2105,18 +2156,21 @@ export declare interface RealtimeChannel extends EventEmitter, listener: messageCallback): void; + /** * Deregisters all listeners for the given event name. * * @param event - The event name. */ unsubscribe(event: string): void; + /** * Deregisters all listeners for all event names in the array. * * @param events - An array of event names. */ unsubscribe(events: Array): void; + /** * Deregisters all listeners to messages on this channel that match the supplied filter. * @@ -2124,12 +2178,14 @@ export declare interface RealtimeChannel extends EventEmitter): void; + /** * Deregisters the given listener (for any/all event names). This removes an earlier subscription. * * @param listener - An event listener function. */ unsubscribe(listener: messageCallback): void; + /** * Deregisters all listeners to messages on this channel. This removes all earlier subscriptions. */ @@ -2139,18 +2195,21 @@ export declare interface RealtimeChannel extends EventEmitter; + /** * Detach from this channel. Any resulting channel state change is emitted to any listeners registered using the {@link EventEmitter.on | `on()`} or {@link EventEmitter.once | `once()`} methods. Once all clients globally have detached from the channel, the channel will be released in the Ably service within two minutes. * * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ detach(): Promise; + /** * Retrieves a {@link PaginatedResult} object, containing an array of historical {@link InboundMessage} objects for the channel. If the channel is configured to persist messages, then messages can be retrieved from history for up to 72 hours in the past. If not, messages can only be retrieved from history for up to two minutes in the past. * @@ -2158,6 +2217,7 @@ export declare interface RealtimeChannel extends EventEmitter>; + /** * Sets the {@link ChannelOptions} for the channel. * @@ -2165,6 +2225,7 @@ export declare interface RealtimeChannel extends EventEmitter; + /** * Registers a listener for messages with a given event name on this channel. The caller supplies a listener function, which is called each time one or more matching messages arrives on the channel. * @@ -2173,6 +2234,7 @@ export declare interface RealtimeChannel extends EventEmitter): Promise; + /** * Registers a listener for messages on this channel for multiple event name values. * @@ -2181,6 +2243,7 @@ export declare interface RealtimeChannel extends EventEmitter, listener?: messageCallback): Promise; + /** * {@label WITH_MESSAGE_FILTER} * @@ -2191,6 +2254,7 @@ export declare interface RealtimeChannel extends EventEmitter): Promise; + /** * Registers a listener for messages on this channel. The caller supplies a listener function, which is called each time one or more messages arrives on the channel. * @@ -2198,6 +2262,7 @@ export declare interface RealtimeChannel extends EventEmitter): Promise; + /** * Publishes a single message to the channel with the given event name and payload. When publish is called with this client library, it won't attempt to implicitly attach to the channel, so long as [transient publishing](https://ably.com/docs/realtime/channels#transient-publish) is available in the library. Otherwise, the client will implicitly attach. * @@ -2206,6 +2271,7 @@ export declare interface RealtimeChannel extends EventEmitter; + /** * Publishes an array of messages to the channel. When publish is called with this client library, it won't attempt to implicitly attach to the channel. * @@ -2213,6 +2279,7 @@ export declare interface RealtimeChannel extends EventEmitter; + /** * Publish a message to the channel. When publish is called with this client library, it won't attempt to implicitly attach to the channel. * @@ -2220,6 +2287,7 @@ export declare interface RealtimeChannel extends EventEmitter; + /** * If the channel is already in the given state, returns a promise which immediately resolves to `null`. Else, calls {@link EventEmitter.once | `once()`} to return a promise which resolves the next time the channel transitions to the given state. * @@ -2276,6 +2344,7 @@ export declare interface Channels { * @returns A {@link Channel} or {@link RealtimeChannel} object. */ get(name: string, channelOptions?: ChannelOptions): T; + /** * Creates a new {@link Channel} or {@link RealtimeChannel} object, with the specified channel {@link DeriveOptions} * and {@link ChannelOptions}, or returns the existing channel object. @@ -2291,6 +2360,7 @@ export declare interface Channels { * @returns A {@link RealtimeChannel} object. */ getDerived(name: string, deriveOptions: DeriveOptions, channelOptions?: ChannelOptions): T; + /** * Releases a {@link Channel} or {@link RealtimeChannel} object, deleting it, and enabling it to be garbage collected. To release a channel, the {@link ChannelState} must be `INITIALIZED`, `DETACHED`, or `FAILED`. * @@ -2335,6 +2405,79 @@ export interface Message { * Timestamp of when the message was received by Ably, as milliseconds since the Unix epoch. */ timestamp?: number; + /** + * The action type of the message, one of the {@link MessageAction} enum values. + */ + action?: MessageAction; + /** + * This message's unique serial. + */ + serial?: string; + /** + * The serial of the message that this message is a reference to. + */ + refSerial?: string; + /** + * The type of reference this message is, in relation to the message it references. + */ + refType?: string; + /** + * If an `update` operation was applied to this message, this will be the timestamp the update occurred. + */ + updatedAt?: number; + /** + * If a `deletion` operation was applied to this message, this will be the timestamp the deletion occurred. + */ + deletedAt?: number; + /** + * If this message resulted from an operation, this will contain the operation details. + */ + operation?: Operation; +} + +/** + * Enum containing the different types of message actions. + */ +export enum MessageAction { + /** + * Message action has not been set. + */ + MessageUnset = 'message_unset', + /** + * Message action for a newly created message. + */ + MessageCreate = 'message_create', + /** + * Message action for an updated message. + */ + MessageUpdate = 'message_update', + /** + * Message action for a deleted message. + */ + MessageDelete = 'message_delete', + /** + * Message action for a newly created annotation. + */ + MessageAnnotationCreate = 'message_annotation_create', + /** + * Message action for a deleted annotation. + */ + MessageAnnotationDelete = 'message_annotation_delete', +} + +export interface Operation { + /** + * The client ID of the client that initiated the operation. + */ + clientId?: string; + /** + * The description provided by the client that initiated the operation. + */ + description?: string; + /** + * A JSON object of string key-value pairs that may contain metadata associated with the operation. + */ + metadata?: Record; } /** @@ -2472,6 +2615,7 @@ export interface Crypto { * @returns A promise which, upon success, will be fulfilled with the generated key as a binary, for example, a byte array. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ generateRandomKey(keyLength?: number): Promise; + /** * Returns a {@link CipherParams} object, using the default values for any fields not supplied by the {@link CipherParamOptions} object. * @@ -2498,18 +2642,22 @@ export declare interface Connection * A unique private connection key used to recover or resume a connection, assigned by Ably. This private connection key can also be used by other REST clients to publish on behalf of this client. See the [publishing over REST on behalf of a realtime client docs](https://ably.com/docs/rest/channels#publish-on-behalf) for more info. (If you want to explicitly recover a connection in a different SDK instance, see createRecoveryKey() instead) */ key?: string; + /** * createRecoveryKey method returns a string that can be used by another client to recover this connection's state in the recover client options property. See [connection state recover options](https://ably.com/docs/connect/states?lang=javascript#connection-state-recovery) for more information. */ createRecoveryKey(): string | null; + /** * The current {@link ConnectionState} of the connection. */ readonly state: ConnectionState; + /** * Causes the connection to close, entering the {@link ConnectionStates.CLOSING} state. Once closed, the library does not attempt to re-establish the connection without an explicit call to {@link Connection.connect | `connect()`}. */ close(): void; + /** * Explicitly calling `connect()` is unnecessary unless the `autoConnect` attribute of the {@link ClientOptions} object is `false`. Unless already connected or connecting, this method causes the connection to open, entering the {@link ConnectionStates.CONNECTING} state. */ @@ -2521,6 +2669,7 @@ export declare interface Connection * @returns A promise which, upon success, will be fulfilled with the response time in milliseconds. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ ping(): Promise; + /** * If the connection is already in the given state, returns a promise which immediately resolves to `null`. Else, calls {@link EventEmitter.once | `once()`} to return a promise which resolves the next time the connection transitions to the given state. * @@ -2563,28 +2712,33 @@ export declare interface PaginatedResult { * Contains the current page of results; for example, an array of {@link InboundMessage} or {@link PresenceMessage} objects for a channel history request. */ items: T[]; + /** * Returns a new `PaginatedResult` for the first page of results. * * @returns A promise which, upon success, will be fulfilled with a page of results for message and presence history, stats, and REST presence requests. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ first(): Promise>; + /** * Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null` is returned. * * @returns A promise which, upon success, will be fulfilled with a page of results for message and presence history, stats, and REST presence requests. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ next(): Promise | null>; + /** * Returns the `PaginatedResult` for the current page of results. */ current(): Promise>; + /** * Returns `true` if there are more pages available by calling next and returns `false` if this page is the last page available. * * @returns Whether or not there are more pages of results. */ hasNext(): boolean; + /** * Returns `true` if this page is the last page and returns `false` if there are more pages available by calling next available. * @@ -2656,6 +2810,7 @@ export declare interface PushAdmin { * A {@link PushChannelSubscriptions} object. */ channelSubscriptions: PushChannelSubscriptions; + /** * Sends a push notification directly to a device, or a group of devices sharing the same `clientId`. * @@ -2677,6 +2832,7 @@ export declare interface PushDeviceRegistrations { * @returns A promise which, upon success, will be fulfilled with a {@link DeviceDetails} object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ save(deviceDetails: DeviceDetails): Promise; + /** * Retrieves the {@link DeviceDetails} of a device registered to receive push notifications using its `deviceId`. * @@ -2684,6 +2840,7 @@ export declare interface PushDeviceRegistrations { * @returns A promise which, upon success, will be fulfilled with a {@link DeviceDetails} object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ get(deviceId: string): Promise; + /** * Retrieves the {@link DeviceDetails} of a device registered to receive push notifications using the `id` property of a {@link DeviceDetails} object. * @@ -2691,6 +2848,7 @@ export declare interface PushDeviceRegistrations { * @returns A promise which, upon success, will be fulfilled with a {@link DeviceDetails} object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ get(deviceDetails: DeviceDetails): Promise; + /** * Retrieves all devices matching the filter `params` provided. Returns a {@link PaginatedResult} object, containing an array of {@link DeviceDetails} objects. * @@ -2698,6 +2856,7 @@ export declare interface PushDeviceRegistrations { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link DeviceDetails} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ list(params: DeviceRegistrationParams): Promise>; + /** * Removes a device registered to receive push notifications from Ably using its `deviceId`. * @@ -2705,6 +2864,7 @@ export declare interface PushDeviceRegistrations { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ remove(deviceId: string): Promise; + /** * Removes a device registered to receive push notifications from Ably using the `id` property of a {@link DeviceDetails} object. * @@ -2712,6 +2872,7 @@ export declare interface PushDeviceRegistrations { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ remove(deviceDetails: DeviceDetails): Promise; + /** * Removes all devices registered to receive push notifications from Ably matching the filter `params` provided. * @@ -2732,6 +2893,7 @@ export declare interface PushChannelSubscriptions { * @returns A promise which, upon success, will be fulfilled with a {@link PushChannelSubscription} object describing the new or updated subscriptions. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ save(subscription: PushChannelSubscription): Promise; + /** * Retrieves all push channel subscriptions matching the filter `params` provided. Returns a {@link PaginatedResult} object, containing an array of {@link PushChannelSubscription} objects. * @@ -2739,6 +2901,7 @@ export declare interface PushChannelSubscriptions { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link PushChannelSubscription} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ list(params: PushChannelSubscriptionParams): Promise>; + /** * Retrieves all channels with at least one device subscribed to push notifications. Returns a {@link PaginatedResult} object, containing an array of channel names. * @@ -2746,6 +2909,7 @@ export declare interface PushChannelSubscriptions { * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of channel names. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ listChannels(params: PushChannelsParams): Promise>; + /** * Unsubscribes a device, or a group of devices sharing the same `clientId` from receiving push notifications on a channel. * @@ -2753,6 +2917,7 @@ export declare interface PushChannelSubscriptions { * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. */ remove(subscription: PushChannelSubscription): Promise; + /** * Unsubscribes all devices from receiving push notifications on a channel that match the filter `params` provided. * @@ -2778,6 +2943,7 @@ export declare class Rest implements RestClient { * @param keyOrToken - The Ably API key or token string used to validate the client. */ constructor(keyOrToken: string); + /** * The cryptographic functions available in the library. */ @@ -2795,6 +2961,7 @@ export declare class Rest implements RestClient { auth: Auth; channels: Channels; + request( method: string, path: string, @@ -2803,13 +2970,18 @@ export declare class Rest implements RestClient { body?: any[] | any, headers?: any, ): Promise>; + stats(params?: StatsParams): Promise>; + time(): Promise; + batchPublish(spec: BatchPublishSpec): Promise>; batchPublish( specs: BatchPublishSpec[], ): Promise[]>; + batchPresence(channels: string[]): Promise[]>; + push: Push; } @@ -2829,6 +3001,7 @@ export declare class Realtime implements RealtimeClient { * @param keyOrToken - The Ably API key or token string used to validate the client. */ constructor(keyOrToken: string); + /** * The cryptographic functions available in the library. */ @@ -2845,11 +3018,15 @@ export declare class Realtime implements RealtimeClient { // Requirements of RealtimeClient clientId: string; + close(): void; + connect(): void; + auth: Auth; channels: Channels; connection: Connection; + request( method: string, path: string, @@ -2858,13 +3035,18 @@ export declare class Realtime implements RealtimeClient { body?: any[] | any, headers?: any, ): Promise>; + stats(params?: StatsParams): Promise>; + time(): Promise; + batchPublish(spec: BatchPublishSpec): Promise>; batchPublish( specs: BatchPublishSpec[], ): Promise[]>; + batchPresence(channels: string[]): Promise[]>; + push: Push; } diff --git a/src/common/lib/types/defaultmessage.ts b/src/common/lib/types/defaultmessage.ts index dfc4a02b1..496720e9c 100644 --- a/src/common/lib/types/defaultmessage.ts +++ b/src/common/lib/types/defaultmessage.ts @@ -5,6 +5,7 @@ import Message, { encode, decode, EncodingDecodingContext, + IncomingMessageValues, } from './message'; import * as API from '../../../../ably'; import Platform from 'common/platform'; @@ -26,7 +27,7 @@ export class DefaultMessage extends Message { // Used by tests static fromValues(values: unknown): Message { - return Object.assign(new Message(), values); + return new Message(values as IncomingMessageValues); } // Used by tests diff --git a/src/common/lib/types/message.ts b/src/common/lib/types/message.ts index 7cc8b80ac..e5a652c60 100644 --- a/src/common/lib/types/message.ts +++ b/src/common/lib/types/message.ts @@ -8,6 +8,16 @@ import { Bufferlike as BrowserBufferlike } from '../../../platform/web/lib/util/ import * as API from '../../../../ably'; import { IUntypedCryptoStatic } from 'common/types/ICryptoStatic'; import { MsgPack } from 'common/types/msgpack'; +import { MessageAction } from '../../../../ably'; + +const MessageActionNumberMap: Record = { + 0: MessageAction.MessageUnset, + 1: MessageAction.MessageCreate, + 2: MessageAction.MessageUpdate, + 3: MessageAction.MessageDelete, + 4: MessageAction.MessageAnnotationCreate, + 5: MessageAction.MessageAnnotationDelete, +}; export type CipherOptions = { channelCipher: { @@ -271,7 +281,7 @@ export async function fromResponseBody( } export function fromValues(values: unknown): Message { - return Object.assign(new Message(), values); + return new Message(values as IncomingMessageValues); } export function fromValuesArray(values: unknown[]): Message[] { @@ -293,6 +303,26 @@ export function getMessagesSize(messages: Message[]): number { return total; } +export type IncomingMessageValues = { + name?: string; + id?: string; + timestamp?: number; + clientId?: string; + connectionId?: string; + connectionKey?: string; + data?: any; + encoding?: string | null; + extras?: any; + size?: number; + action?: number | MessageAction; // Allow both number and MessageAction + serial?: string; + refSerial?: string; + refType?: string; + updatedAt?: number; + deletedAt?: number; + operation?: API.Operation; +}; + class Message { name?: string; id?: string; @@ -304,6 +334,25 @@ class Message { encoding?: string | null; extras?: any; size?: number; + action?: MessageAction; + serial?: string; + refSerial?: string; + refType?: string; + updatedAt?: number; + deletedAt?: number; + operation?: API.Operation; + + constructor(values: IncomingMessageValues) { + // Copy all provided properties to the instance + Object.assign(this, values); + + // Translate the action number to the corresponding MessageAction enum + if (typeof values.action === 'number') { + this.action = MessageActionNumberMap[values.action as number]; + } else { + this.action = values.action; + } + } /** * Overload toJSON() to intercept JSON.stringify() @@ -334,6 +383,13 @@ class Message { connectionId: this.connectionId, connectionKey: this.connectionKey, extras: this.extras, + serial: this.serial, + action: this.action, + refSerial: this.refSerial, + refType: this.refType, + updatedAt: this.updatedAt, + deletedAt: this.deletedAt, + operation: this.operation, encoding, data, }; @@ -355,6 +411,14 @@ class Message { else result += '; data (json)=' + JSON.stringify(this.data); } if (this.extras) result += '; extras=' + JSON.stringify(this.extras); + + if (this.action) result += '; action=' + this.action.toString(); + if (this.serial) result += '; serial=' + this.serial; + if (this.refSerial) result += '; refSerial=' + this.refSerial; + if (this.refType) result += '; refType=' + this.refType; + if (this.updatedAt) result += '; updatedAt=' + this.updatedAt; + if (this.deletedAt) result += '; deletedAt=' + this.deletedAt; + if (this.operation) result += '; operation=' + JSON.stringify(this.operation); result += ']'; return result; }