@@ -12,11 +12,12 @@ import {
1212 EventCallback ,
1313 RealtimeChannel ,
1414 RealtimeClient ,
15+ RestClient ,
1516 StatusSubscription ,
1617 Subscription ,
1718 __livetype ,
1819} from './ably' ;
19- import { BaseRealtime } from './modular' ;
20+ import { BaseRealtime , BaseRest , Rest } from './modular' ;
2021/* eslint-enable no-unused-vars, @typescript-eslint/no-unused-vars */
2122
2223/**
@@ -67,7 +68,256 @@ export type ObjectsEventCallback = () => void;
6768export type BatchFunction < T extends LiveObject > = ( ctx : BatchContext < T > ) => void ;
6869
6970/**
70- * Enables the Objects to be read, modified and subscribed to for a channel.
71+ * Enables REST-based operations on Objects on a channel.
72+ */
73+ export declare interface RestObject {
74+ /**
75+ * Reads object data from the channel in a compact format.
76+ * Uses the channel's root object as the entrypoint when no objectId is provided.
77+ *
78+ * @param params - Optional parameters to specify the object to fetch and the format of the returned data.
79+ * @returns A promise that resolves to the object data in compact format, or `undefined` if the specified objectId/path does not resolve to an object.
80+ */
81+ get ( params ?: Omit < GetObjectParams , 'compact' > & { compact ?: true } ) : Promise < RestCompactObjectData | undefined > ;
82+ /**
83+ * Reads object data from the channel in expanded format.
84+ * Uses the channel's root object as the entrypoint when no objectId is provided.
85+ *
86+ * @param params - Parameters specifying the object to fetch with `compact: false`.
87+ * @returns A promise that resolves to the object data in expanded format, or `undefined` if the specified objectId/path does not resolve to an object.
88+ */
89+ get ( params : Omit < GetObjectParams , 'compact' > & { compact : false } ) : Promise < RestLiveObject | undefined > ;
90+ /**
91+ * Reads object data from the channel.
92+ * Uses the channel's root object as the entrypoint when no objectId is provided.
93+ *
94+ * @param params - Optional parameters to specify the object to fetch and the format of the returned data.
95+ * @returns A promise that resolves to the object data in the requested format, or `undefined` if the specified objectId/path does not resolve to an object.
96+ */
97+ get ( params ?: GetObjectParams ) : Promise < RestCompactObjectData | RestLiveObject | undefined > ;
98+
99+ /**
100+ * Publishes one or more operations to modify objects on the channel.
101+ *
102+ * @param op - A single operation or array of operations to publish.
103+ * @returns A promise that resolves to a {@link RestObjectPublishResult} containing information about the published operations.
104+ */
105+ publish ( op : RestObjectOperation | RestObjectOperation [ ] ) : Promise < RestObjectPublishResult > ;
106+ }
107+
108+ /**
109+ * Base interface for all REST object operations. Contains common fields shared across all operation types.
110+ */
111+ export interface RestObjectOperationBase {
112+ /**
113+ * An ID associated with the message. Clients may set this field explicitly when publishing an operation to enable
114+ * idempotent publishing. If not set, this will be generated by the server.
115+ */
116+ id ?: string ;
117+ /**
118+ * A JSON object of arbitrary key-value pairs that may contain metadata, and/or ancillary payloads. Valid payloads include `headers`.
119+ */
120+ extras ?: {
121+ /**
122+ * A set of key–value pair headers included with this object message.
123+ */
124+ headers ?: Record < string , string > ;
125+ [ key : string ] : any ;
126+ } ;
127+ }
128+
129+ // Enforce exactly one target at compile time using a union of the types below.
130+ /**
131+ * Targets an object by its object ID.
132+ */
133+ type TargetByObjectId = { objectId : string ; path ?: never } ;
134+
135+ /**
136+ * Targets an object by its location using the path.
137+ * Paths are expressed relative to the structure of the object as defined by the compact view of the object tree.
138+ */
139+ type TargetByPath = { path : string ; objectId ?: never } ;
140+
141+ /**
142+ * Base type for operations that can target objects either by object ID or by path.
143+ * Ensures that exactly one targeting method is specified.
144+ */
145+ export type AnyTargetOperationBase = RestObjectOperationBase & ( TargetByObjectId | TargetByPath ) ;
146+
147+ /**
148+ * Operation to create a new map object at the specified path with initial entries.
149+ */
150+ export type OperationMapCreate = RestObjectOperationBase &
151+ TargetByPath & {
152+ operation : ObjectOperationActions . MAP_CREATE ;
153+ entries : Record < string , PrimitiveOrObjectReference > ;
154+ } ;
155+
156+ /**
157+ * Operation to set a key to a specified value in an existing map object.
158+ * Can target the map by either object ID or path.
159+ */
160+ export type OperationMapSet = AnyTargetOperationBase & {
161+ operation : ObjectOperationActions . MAP_SET ;
162+ key : string ;
163+ value : PrimitiveOrObjectReference ;
164+ encoding ?: string ;
165+ } ;
166+
167+ /**
168+ * Operation to remove a key from an existing map object.
169+ * Can target the map by either object ID or path.
170+ */
171+ export type OperationMapRemove = AnyTargetOperationBase & {
172+ operation : ObjectOperationActions . MAP_REMOVE ;
173+ key : string ;
174+ } ;
175+
176+ /**
177+ * Operation to create a new counter object at the specified path with an initial count value.
178+ */
179+ export type OperationCounterCreate = RestObjectOperationBase &
180+ TargetByPath & {
181+ operation : ObjectOperationActions . COUNTER_CREATE ;
182+ count : number ;
183+ } ;
184+
185+ /**
186+ * Operation to increment (or decrement with negative values) an existing counter object.
187+ * Can target the counter by either object ID or path.
188+ */
189+ export type OperationCounterInc = AnyTargetOperationBase & {
190+ operation : ObjectOperationActions . COUNTER_INC ;
191+ amount : number ;
192+ } ;
193+
194+ /**
195+ * Union type representing all possible REST object operations.
196+ */
197+ export type RestObjectOperation =
198+ | OperationMapCreate
199+ | OperationMapSet
200+ | OperationMapRemove
201+ | OperationCounterCreate
202+ | OperationCounterInc ;
203+
204+ /**
205+ * Result returned after successfully publishing object operations via REST.
206+ * Contains information about the published message and affected object IDs.
207+ */
208+ export interface RestObjectPublishResult {
209+ /** The ID of the message containing the published operations. */
210+ messageId : string ;
211+ /** The name of the channel the object message was published to. */
212+ channel : string ;
213+ /**
214+ * Array of object IDs that were affected by the operations.
215+ * May include multiple IDs for wildcard paths and batch operations.
216+ */
217+ objectIds : string [ ] ;
218+ }
219+
220+ /**
221+ * Compact representation of object data returned from {@link RestObject.get} when `compact=true` (default).
222+ * Provides a JSON-like view with primitive values, nested objects, and object references for handling cycles.
223+ */
224+ export type RestCompactObjectData =
225+ | string
226+ | number
227+ | boolean
228+ | null
229+ | JsonArray
230+ | JsonObject
231+ | { objectId : string } // cyclic references handling
232+ | { [ key : string ] : RestCompactObjectData } ;
233+
234+ /**
235+ * Object representation returned from {@link RestObject.get} when `compact=false`.
236+ * Provides an expanded structural view with object metadata.
237+ */
238+ export type RestLiveObject = RestLiveMap | RestLiveCounter | AnyRestLiveObject ;
239+
240+ /**
241+ * Expanded representation of a map object with metadata.
242+ */
243+ export interface RestLiveMap {
244+ /** The ID of the map object. */
245+ objectId : string ;
246+ /** Describes the value of a map object. */
247+ map : {
248+ /** The conflict-resolution semantics used by the map object, one of the {@link ObjectsMapSemantics} enum values. */
249+ semantics : ObjectsMapSemantics ;
250+ /** The map entries, indexed by key. */
251+ entries : Record < string , RestObjectMapEntry > ;
252+ } ;
253+ }
254+
255+ /**
256+ * Describes a value at a specific key in a map object.
257+ */
258+ export interface RestObjectMapEntry {
259+ /** The value associated with this map entry. */
260+ data : RestLiveObject | RestObjectData ;
261+ }
262+
263+ /**
264+ * Represents a value in an object on a channel.
265+ * Either a primitive data or a reference to another object.
266+ */
267+ export interface RestObjectData {
268+ /** Reference to another object by its ID. */
269+ objectId ?: string ;
270+ /** A numeric value. */
271+ number ?: number ;
272+ /** A boolean value. */
273+ boolean ?: boolean ;
274+ /** A string value. */
275+ string ?: string ;
276+ /** A binary value. Typed differently depending on platform (`Buffer` in Node.js, `ArrayBuffer` elsewhere). */
277+ bytes ?: Buffer | ArrayBuffer ;
278+ /** A JSON value (array or object). */
279+ json ?: JsonArray | JsonObject ;
280+ }
281+
282+ /**
283+ * Expanded representation of a counter object with metadata.
284+ */
285+ export interface RestLiveCounter {
286+ /** The ID of the counter object. */
287+ objectId : string ;
288+ /** Describes the value of a counter object. */
289+ counter : {
290+ /** Holds the value of the counter. */
291+ data : {
292+ /** The value of the counter. */
293+ number : number ;
294+ } ;
295+ } ;
296+ }
297+
298+ /**
299+ * Fallback type for compatibility with future object types.
300+ */
301+ export type AnyRestLiveObject = {
302+ /** The ID of the object, available for all object types. */
303+ objectId : string ;
304+ } ;
305+
306+ /**
307+ * Request parameters for {@link RestObject.get}.
308+ * All parameters are optional since the default behavior is to fetch the channel's root object with `compact=true`.
309+ */
310+ export interface GetObjectParams {
311+ /** The object ID to fetch. If omitted, the entrypoint is the channel's root object. */
312+ objectId ?: string ;
313+ /** Path evaluated relative to the entrypoint (root or specified objectId). */
314+ path ?: string ;
315+ /** Whether to return compact representation. Defaults to true. */
316+ compact ?: boolean ;
317+ }
318+
319+ /**
320+ * Enables the Objects to be read, modified and subscribed to for a realtime channel.
71321 */
72322export declare interface RealtimeObject {
73323 /**
@@ -124,6 +374,14 @@ export type Primitive =
124374 | JsonArray
125375 | JsonObject ;
126376
377+ /**
378+ * Primitive types and object references that may appear in `data` fields
379+ * of response bodies when using the Objects REST API.
380+ *
381+ * References to other objects are represented as `{ objectId: string }`.
382+ */
383+ export type PrimitiveOrObjectReference = Primitive | { objectId : string } ;
384+
127385/**
128386 * Represents a JSON-encodable value.
129387 */
@@ -1492,7 +1750,7 @@ declare namespace ObjectOperationActions {
14921750}
14931751
14941752/**
1495- * The possible values of the `action` field of an {@link ObjectOperation }.
1753+ * Describes object operation types for { @link ObjectOperation} and {@link RestObjectOperation }.
14961754 */
14971755export type ObjectOperationAction =
14981756 | ObjectOperationActions . MAP_CREATE
@@ -1793,22 +2051,23 @@ export class LiveCounter {
17932051}
17942052
17952053/**
1796- * The LiveObjects plugin that provides a {@link RealtimeClient} instance with the ability to use LiveObjects functionality.
2054+ * The LiveObjects plugin that provides a {@link RestClient} or { @link RealtimeClient} instance with the ability to use LiveObjects functionality.
17972055 *
1798- * To create a client that includes this plugin, include it in the client options that you pass to the {@link RealtimeClient.constructor}:
2056+ * To create a client that includes this plugin, include it in the client options that you pass to the {@link RestClient.constructor} or { @link RealtimeClient.constructor}:
17992057 *
18002058 * ```javascript
18012059 * import { Realtime } from 'ably';
18022060 * import { LiveObjects } from 'ably/liveobjects';
18032061 * const realtime = new Realtime({ ...options, plugins: { LiveObjects } });
18042062 * ```
18052063 *
1806- * The LiveObjects plugin can also be used with a {@link BaseRealtime} client:
2064+ * The LiveObjects plugin can also be used with a {@link BaseRest} or {@link BaseRealtime} client,
2065+ * with the additional requirement that you must also use the {@link Rest} plugin
18072066 *
18082067 * ```javascript
1809- * import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modular';
2068+ * import { BaseRealtime, Rest, WebSocketTransport, FetchRequest } from 'ably/modular';
18102069 * import { LiveObjects } from 'ably/liveobjects';
1811- * const realtime = new BaseRealtime({ ...options, plugins: { WebSocketTransport, FetchRequest, LiveObjects } });
2070+ * const realtime = new BaseRealtime({ ...options, plugins: { Rest, WebSocketTransport, FetchRequest, LiveObjects } });
18122071 * ```
18132072 *
18142073 * You can also import individual utilities alongside the plugin:
@@ -1832,3 +2091,17 @@ declare module 'ably' {
18322091 object : RealtimeObject ;
18332092 }
18342093}
2094+
2095+ /**
2096+ * Module augmentation to add the `object` property to `RestChannel` when
2097+ * importing from 'ably/liveobjects'. This ensures all LiveObjects types come from
2098+ * the same module (CJS or ESM), avoiding type incompatibility issues.
2099+ */
2100+ declare module 'ably' {
2101+ interface RestChannel {
2102+ /**
2103+ * A {@link RestObject} object.
2104+ */
2105+ object : RestObject ;
2106+ }
2107+ }
0 commit comments