From dc6a9486a38d734cefd927e38279ba7f1b3a873c Mon Sep 17 00:00:00 2001 From: umair Date: Tue, 9 Jun 2026 17:10:00 +0100 Subject: [PATCH] DX-1211: rewrite RealtimeChannel interface docstrings (prerequisites, side-effects, failure modes) Surface call-site prerequisites and failure modes across the RealtimeChannel public surface per docstringRules.md (terse folded prose + @see companion): - subscribe(): silent missing-`subscribe`-mode trap + strictMode aside (DX-1211 core) - params/errorReason: guard against undefined/null despite the declared type - history(): persistence channel-rule prerequisite; fix "presence members" @param bug - message ops (get/update/delete/append/getMessageVersions): async-reject framing and message-interactions channel-rule prerequisite - push: universal missing-plugin throw kept; presence/annotations left as-is (bundled by the default build) TypeDoc (treatWarningsAsErrors), prettier, and eslint all pass. Co-Authored-By: Claude Opus 4.8 (1M context) --- ably.d.ts | 164 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 135 insertions(+), 29 deletions(-) diff --git a/ably.d.ts b/ably.d.ts index 472551825..f18cbe665 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -2627,7 +2627,9 @@ export declare interface RealtimeChannel extends EventEmitter): void; /** - * Deregisters the given listener from all event names in the array. + * Deregisters the given listener from all event names in the array. This only removes the local listeners and does not detach the channel. * * @param events - An array of event names. * @param listener - An event listener function. + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#unsubscribe */ unsubscribe(events: Array, listener: messageCallback): void; /** - * Deregisters all listeners for the given event name. + * Deregisters all listeners for the given event name. This only removes the local listeners and does not detach the channel. * * @param event - The event name. + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#unsubscribe */ unsubscribe(event: string): void; /** - * Deregisters all listeners for all event names in the array. + * Deregisters all listeners for all event names in the array. This only removes the local listeners and does not detach the channel. * * @param events - An array of event names. + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#unsubscribe */ unsubscribe(events: Array): void; /** - * Deregisters all listeners to messages on this channel that match the supplied filter. + * Deregisters listeners to messages on this channel that match the supplied filter, removing an earlier filtered subscription. This only removes the local listeners and does not detach the channel. * * @param filter - A {@link MessageFilter}. * @param listener - An event listener function. + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#unsubscribe */ unsubscribe(filter: MessageFilter, listener?: messageCallback): void; /** - * Deregisters the given listener (for any/all event names). This removes an earlier subscription. + * Deregisters the given listener (for any/all event names), removing an earlier subscription. This only removes the local listener and does not detach the channel. * * @param listener - An event listener function. + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#unsubscribe */ unsubscribe(listener: messageCallback): void; /** - * Deregisters all listeners to messages on this channel. This removes all earlier subscriptions. + * Deregisters all listeners to messages on this channel, removing all earlier subscriptions. This only removes the local listeners and does not detach the channel, so the channel stays attached. + * + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#unsubscribe */ unsubscribe(): void; /** @@ -2706,7 +2724,9 @@ 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. + * 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 is released in the Ably service within two minutes. Detaching from a `suspended` or already `detached` channel resolves without further action, but detaching from a `failed` channel rejects with an {@link ErrorInfo}, in which case release the channel and get it again to start afresh. * * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. + * @example + * ```ts + * await channel.detach(); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#detach */ 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. + * Retrieves a {@link PaginatedResult} object, containing an array of historical {@link InboundMessage} objects for the channel. Messages are returned from durable storage only when message persistence is enabled for the channel by a channel rule; without it, only messages from the last two minutes, the service's default retention, are returned. * - * @param params - A set of parameters which are used to specify which presence members should be retrieved. + * @param params - A set of parameters which are used to specify which messages should be retrieved. * @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. + * @example + * ```ts + * const result = await channel.history({ limit: 25 }); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#history + * @see https://ably.com/docs/storage-history/storage */ history(params?: RealtimeHistoryParams): Promise>; /** @@ -2747,43 +2783,68 @@ export declare interface RealtimeChannel extends EventEmitter>): never; /** - * Sets the {@link ChannelOptions} for the channel. + * Sets the {@link ChannelOptions} for the channel. If the channel is already attached or attaching and the new {@link ChannelOptions.modes} or {@link ChannelOptions.params} differ from the current ones, this triggers a live re-attach to apply them, and the returned promise resolves only once the server confirms the new options, rejecting with an {@link ErrorInfo} if the channel detaches or fails in the meantime. Otherwise the new options are stored for the next attach. The promise also rejects with an {@link ErrorInfo} when the supplied options are invalid. * * @param options - A {@link ChannelOptions} object. * @returns A promise which resolves upon success of the operation and rejects with an {@link ErrorInfo} object upon its failure. + * @example + * ```ts + * await channel.setOptions({ params: { rewind: '1' } }); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#set-options */ setOptions(options: ChannelOptions): Promise; /** - * 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. + * 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. Implicitly attaches the channel unless {@link ChannelOptions.attachOnSubscribe} is `false`. Requires the `subscribe` mode (granted by default unless {@link ChannelOptions.modes} excludes it); if the channel attaches without it the server never delivers messages, so the listener silently never fires and a warning is logged rather than the call rejecting (or it rejects with a hinted {@link ErrorInfo} when {@link ClientOptions.strictMode} is enabled). * * @param event - The event name. * @param listener - An event listener function. * @returns A promise which, upon successful attachment to the channel, will be fulfilled with a {@link ChannelStateChange} object. If the channel was already attached the promise will be resolved with `null`. Upon failure, the promise will be rejected with an {@link ErrorInfo} object. + * @example + * ```ts + * await channel.subscribe('event', (message) => console.log(message.data)); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#subscribe */ subscribe(event: string, listener?: messageCallback): Promise; /** - * Registers a listener for messages on this channel for multiple event name values. + * Registers a listener for messages on this channel for multiple event name values. Implicitly attaches the channel unless {@link ChannelOptions.attachOnSubscribe} is `false`. Requires the `subscribe` mode (granted by default unless {@link ChannelOptions.modes} excludes it); if the channel attaches without it the server never delivers messages, so the listener silently never fires and a warning is logged rather than the call rejecting (or it rejects with a hinted {@link ErrorInfo} when {@link ClientOptions.strictMode} is enabled). * * @param events - An array of event names. * @param listener - An event listener function. * @returns A promise which, upon successful attachment to the channel, will be fulfilled with a {@link ChannelStateChange} object. If the channel was already attached the promise will be resolved with `null`. Upon failure, the promise will be rejected with an {@link ErrorInfo} object. + * @example + * ```ts + * await channel.subscribe(['event1', 'event2'], (message) => console.log(message.data)); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#subscribe */ subscribe(events: Array, listener?: messageCallback): Promise; /** * {@label WITH_MESSAGE_FILTER} * - * Registers a listener for messages on this channel that match the supplied filter. + * Registers a listener for messages on this channel that match the supplied filter. Implicitly attaches the channel unless {@link ChannelOptions.attachOnSubscribe} is `false`. Requires the `subscribe` mode (granted by default unless {@link ChannelOptions.modes} excludes it); if the channel attaches without it the server never delivers messages, so the listener silently never fires and a warning is logged rather than the call rejecting (or it rejects with a hinted {@link ErrorInfo} when {@link ClientOptions.strictMode} is enabled). * * @param filter - A {@link MessageFilter}. * @param listener - An event listener function. * @returns A promise which, upon successful attachment to the channel, will be fulfilled with a {@link ChannelStateChange} object. If the channel was already attached the promise will be resolved with `null`. Upon failure, the promise will be rejected with an {@link ErrorInfo} object. + * @example + * ```ts + * await channel.subscribe({ name: 'event' }, (message) => console.log(message.data)); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#subscribe */ subscribe(filter: MessageFilter, listener?: messageCallback): 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. + * 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. Implicitly attaches the channel unless {@link ChannelOptions.attachOnSubscribe} is `false`. Requires the `subscribe` mode (granted by default unless {@link ChannelOptions.modes} excludes it); if the channel attaches without it the server never delivers messages, so the listener silently never fires and a warning is logged rather than the call rejecting (or it rejects with a hinted {@link ErrorInfo} when {@link ClientOptions.strictMode} is enabled). * * @param callback - An event listener function. * @returns A promise which, upon successful attachment to the channel, will be fulfilled with a {@link ChannelStateChange} object. If the channel was already attached the promise will be resolved with `null`. Upon failure, the promise will be rejected with an {@link ErrorInfo} object. + * @example + * ```ts + * await channel.subscribe((message) => console.log(message.data)); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#subscribe */ subscribe(callback: messageCallback): Promise; /** @@ -2802,28 +2863,43 @@ export declare interface RealtimeChannel extends EventEmitter, callback: ErrorCallback): never; /** - * 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. + * Publishes a single message to the channel with the given event name and payload. Publishing does not attach the channel, so unlike {@link RealtimeChannel.subscribe | `subscribe()`}, {@link RealtimePresence.enter | `enter()`}, and {@link RealtimePresence.get | `get()`} a publish-only client need not attach or subscribe first. * * @param name - The event name. * @param data - The message payload. * @param options - Optional parameters sent as part of the protocol message. * @returns A promise which, upon success, will be fulfilled with a {@link PublishResult} object containing the serial of the published message. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * await channel.publish('event', { text: 'hello' }); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#publish */ publish(name: string, data: any, options?: PublishOptions): Promise; /** - * 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. + * Publishes an array of messages to the channel. Publishing does not attach the channel, so unlike {@link RealtimeChannel.subscribe | `subscribe()`}, {@link RealtimePresence.enter | `enter()`}, and {@link RealtimePresence.get | `get()`} a publish-only client need not attach or subscribe first. * * @param messages - An array of {@link Message} objects. * @param options - Optional parameters sent as part of the protocol message. * @returns A promise which, upon success, will be fulfilled with a {@link PublishResult} object containing the serials of the published messages. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * await channel.publish([{ name: 'event', data: { text: 'hello' } }]); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#publish */ publish(messages: Message[], options?: PublishOptions): Promise; /** - * Publish a message to the channel. When publish is called with this client library, it won't attempt to implicitly attach to the channel. + * Publish a message to the channel. Publishing does not attach the channel, so unlike {@link RealtimeChannel.subscribe | `subscribe()`}, {@link RealtimePresence.enter | `enter()`}, and {@link RealtimePresence.get | `get()`} a publish-only client need not attach or subscribe first. * * @param message - A {@link Message} object. * @param options - Optional parameters sent as part of the protocol message. * @returns A promise which, upon success, will be fulfilled with a {@link PublishResult} object containing the serial of the published message. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * await channel.publish({ name: 'event', data: { text: 'hello' } }); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#publish */ publish(message: Message, options?: PublishOptions): Promise; /** @@ -2842,51 +2918,81 @@ export declare interface RealtimeChannel extends EventEmitter; /** - * Retrieves the latest version of a specific message by its serial identifier. + * Retrieves the latest version of a specific message by its serial identifier. Retrievable messages require message interactions (mutable messages) to be enabled for the channel by a channel rule. The supplied serial or {@link Message} must carry a populated `serial`, which is present on a {@link Message} received from a subscribe callback but not on a freshly constructed one; if the serial is missing the promise rejects with an {@link ErrorInfo}. * * @param serialOrMessage - Either the serial identifier string of the message to retrieve, or a {@link Message} object containing a populated `serial` field. * @returns A promise which, upon success, will be fulfilled with a {@link Message} object representing the latest version of the message. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * const message = await channel.getMessage(serial); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#get-message */ getMessage(serialOrMessage: string | Message): Promise; /** - * Publishes an update to an existing message with patch semantics. Non-null `name`, `data`, and `extras` fields in the provided message will replace the corresponding fields in the existing message, while null fields will be left unchanged. + * Publishes an update to an existing message with patch semantics. Non-null `name`, `data`, and `extras` fields in the provided message will replace the corresponding fields in the existing message, while null fields will be left unchanged. The namespace must have message interactions (updates) enabled by a channel rule, and the supplied `message` must carry the `serial` it was given when published (pass the {@link Message} received in a subscribe callback, not a freshly constructed object); otherwise the promise rejects with an {@link ErrorInfo}. * * @param message - A {@link Message} object containing a populated `serial` field and the fields to update. * @param operation - An optional {@link MessageOperation} object containing metadata about the update operation. * @param options - Optional parameters to modify how the publish is made. * @returns A promise which, upon success, will be fulfilled with an {@link UpdateDeleteResult} object containing the serial of the new version of the message. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * await channel.updateMessage({ ...message, data: 'edited text' }); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#update-message */ updateMessage(message: Message, operation?: MessageOperation, options?: PublishOptions): Promise; /** - * Marks a message as deleted by publishing an update with an action of `MESSAGE_DELETE`. This does not remove the message from the server, and the full message history remains accessible. Uses patch semantics: non-null `name`, `data`, and `extras` fields in the provided message will replace the corresponding fields in the existing message, while null fields will be left unchanged (meaning that if you for example want the `MESSAGE_DELETE` to have an empty data, you should explicitly set the `data` to an empty object). + * Marks a message as deleted by publishing an update with an action of `MESSAGE_DELETE`. This does not remove the message from the server, and the full message history remains accessible. Uses patch semantics: non-null `name`, `data`, and `extras` fields in the provided message will replace the corresponding fields in the existing message, while null fields will be left unchanged (meaning that if you for example want the `MESSAGE_DELETE` to have an empty data, you should explicitly set the `data` to an empty object). Requires message interactions (deletes) to be enabled for the channel by a channel rule, and the message must carry a `serial`, so pass the {@link Message} you received from a subscribe callback rather than a freshly constructed object; otherwise the call rejects with an {@link ErrorInfo}. * * @param message - A {@link Message} object containing a populated `serial` field. * @param operation - An optional {@link MessageOperation} object containing metadata about the delete operation. * @param options - Optional parameters to modify how the publish is made. * @returns A promise which, upon success, will be fulfilled with an {@link UpdateDeleteResult} object containing the serial of the new version of the message. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * const result = await channel.deleteMessage(message); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#delete-message */ deleteMessage(message: Message, operation?: MessageOperation, options?: PublishOptions): Promise; /** - * Appends data to an existing message. The supplied `data` field is appended to the previous message's data, while all other fields (`name`, `extras`) replace the previous values if provided. + * Appends data to an existing message. The supplied `data` field is appended to the previous message's data, while all other fields (`name`, `extras`) replace the previous values if provided. Requires message interactions (mutable messages) to be enabled for the channel by a channel rule, and the supplied {@link Message} must carry the `serial` it received from a subscribe callback, otherwise the call rejects with an {@link ErrorInfo}. * * @param message - A {@link Message} object containing a populated `serial` field and the data to append. * @param operation - An optional {@link MessageOperation} object containing metadata about the append operation. * @param options - Optional parameters to modify how the publish is made. * @returns A promise which, upon success, will be fulfilled with an {@link UpdateDeleteResult} object containing the serial of the new version of the message. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * const result = await channel.appendMessage(message); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#append-message */ appendMessage(message: Message, operation?: MessageOperation, options?: PublishOptions): Promise; /** - * Retrieves all historical versions of a specific message, ordered by version. This includes the original message and all subsequent updates or delete operations. + * Retrieves all historical versions of a specific message, ordered by version. This includes the original message and all subsequent updates or delete operations. The message must carry a `serial`, so pass the {@link Message} from a subscribe callback or its serial string, otherwise the call rejects with an {@link ErrorInfo}. Message versions exist only when message interactions (updates and deletes) are enabled for the channel by a channel rule. * * @param serialOrMessage - Either the serial identifier string of the message whose versions are to be retrieved, or a {@link Message} object containing a populated `serial` field. * @param params - Optional parameters sent as part of the query string. * @returns A promise which, upon success, will be fulfilled with a {@link PaginatedResult} object containing an array of {@link Message} objects representing all versions of the message. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. + * @example + * ```ts + * const versions = await channel.getMessageVersions(message); + * ``` + * @see https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel#get-message-versions */ getMessageVersions( serialOrMessage: string | Message,