{
  "version": 3,
  "sources": ["../src/plugins/liveobjects/objectid.ts", "../src/plugins/liveobjects/objectmessage.ts", "../src/plugins/liveobjects/livecountervaluetype.ts", "../src/plugins/liveobjects/livemap.ts", "../src/plugins/liveobjects/constants.ts", "../src/plugins/liveobjects/liveobject.ts", "../src/plugins/liveobjects/defaults.ts", "../src/plugins/liveobjects/objectspool.ts", "../src/plugins/liveobjects/batchcontext.ts", "../src/plugins/liveobjects/rootbatchcontext.ts", "../src/plugins/liveobjects/instance.ts", "../src/plugins/liveobjects/pathobject.ts", "../src/plugins/liveobjects/pathobjectsubscriptionregister.ts", "../src/plugins/liveobjects/syncobjectspool.ts", "../src/plugins/liveobjects/realtimeobject.ts", "../src/plugins/liveobjects/livecounter.ts", "../src/plugins/liveobjects/livemapvaluetype.ts", "../src/plugins/liveobjects/restobject.ts", "../src/plugins/liveobjects/index.ts"],
  "sourcesContent": ["import type BaseClient from 'common/lib/client/baseclient';\r\nimport type Platform from 'common/platform';\r\n\r\nexport type LiveObjectType = 'map' | 'counter';\r\n\r\n// 12 bytes of entropy base64-encode to a 16-character string, the RTLCV4d/RTLMV4g minimum\r\nconst NONCE_ENTROPY_BYTES = 12;\r\n\r\n/**\r\n * Represents a parsed object id.\r\n *\r\n * @internal\r\n */\r\nexport class ObjectId {\r\n  private constructor(\r\n    readonly type: LiveObjectType,\r\n    readonly hash: string,\r\n    readonly msTimestamp: number,\r\n  ) {}\r\n\r\n  /**\r\n   * Generates a unique random string nonce with 16+ characters, as required for\r\n   * object id creation (RTLCV4d, RTLMV4g). 12 bytes of entropy base64-encode to\r\n   * exactly 16 characters.\r\n   */\r\n  static async generateNonce(client: BaseClient): Promise<string> {\r\n    return client.Utils.randomString(NONCE_ENTROPY_BYTES);\r\n  }\r\n\r\n  static fromInitialValue(\r\n    platform: typeof Platform,\r\n    objectType: LiveObjectType,\r\n    initialValue: string,\r\n    nonce: string,\r\n    msTimestamp: number,\r\n  ): ObjectId {\r\n    const valueForHashBuffer = platform.BufferUtils.concat([\r\n      platform.BufferUtils.utf8Encode(initialValue),\r\n      platform.BufferUtils.utf8Encode(':'),\r\n      platform.BufferUtils.utf8Encode(nonce),\r\n    ]);\r\n    const hashBuffer = platform.BufferUtils.sha256(valueForHashBuffer);\r\n    const hash = platform.BufferUtils.base64UrlEncode(hashBuffer);\r\n\r\n    return new ObjectId(objectType, hash, msTimestamp);\r\n  }\r\n\r\n  /**\r\n   * Create ObjectId instance from hashed object id string.\r\n   */\r\n  static fromString(client: BaseClient, objectId: string | null | undefined): ObjectId {\r\n    if (client.Utils.isNil(objectId)) {\r\n      throw new client.ErrorInfo('Invalid object id string', 92000, 400);\r\n    }\r\n\r\n    // RTO6b1\r\n    const [type, rest] = objectId.split(':');\r\n    if (!type || !rest) {\r\n      throw new client.ErrorInfo('Invalid object id string', 92000, 400);\r\n    }\r\n\r\n    if (!['map', 'counter'].includes(type)) {\r\n      throw new client.ErrorInfo(`Invalid object type in object id: ${objectId}`, 92000, 400);\r\n    }\r\n\r\n    const [hash, msTimestamp] = rest.split('@');\r\n    if (!hash || !msTimestamp) {\r\n      throw new client.ErrorInfo('Invalid object id string', 92000, 400);\r\n    }\r\n\r\n    if (!Number.isInteger(Number.parseInt(msTimestamp))) {\r\n      throw new client.ErrorInfo('Invalid object id string', 92000, 400);\r\n    }\r\n\r\n    return new ObjectId(type as LiveObjectType, hash, Number.parseInt(msTimestamp));\r\n  }\r\n\r\n  toString(): string {\r\n    return `${this.type}:${this.hash}@${this.msTimestamp}`;\r\n  }\r\n}\r\n", "import type BaseClient from 'common/lib/client/baseclient';\r\nimport type RealtimeChannel from 'common/lib/client/realtimechannel';\r\nimport type { MessageEncoding } from 'common/lib/types/basemessage';\r\nimport type * as Utils from 'common/lib/util/utils';\r\nimport type * as ObjectsApi from '../../../liveobjects';\r\n\r\nexport type EncodeObjectDataFunction<TData = ObjectData | WireObjectData> = (data: TData) => WireObjectData;\r\n\r\n/** @spec OOP2 */\r\nexport enum ObjectOperationAction {\r\n  MAP_CREATE = 0,\r\n  MAP_SET = 1,\r\n  MAP_REMOVE = 2,\r\n  COUNTER_CREATE = 3,\r\n  COUNTER_INC = 4,\r\n  OBJECT_DELETE = 5,\r\n  MAP_CLEAR = 6,\r\n}\r\n\r\nconst operationActions: ObjectsApi.ObjectOperationAction[] = [\r\n  'map.create',\r\n  'map.set',\r\n  'map.remove',\r\n  'counter.create',\r\n  'counter.inc',\r\n  'object.delete',\r\n  'map.clear',\r\n];\r\n\r\nexport function decodeObjectOperationAction(action: ObjectOperationAction): ObjectsApi.ObjectOperationAction {\r\n  return operationActions[action] || 'unknown';\r\n}\r\n\r\n/** @spec OMP2 */\r\nexport enum ObjectsMapSemantics {\r\n  LWW = 0,\r\n}\r\n\r\nconst mapSemantics: ObjectsApi.ObjectsMapSemantics[] = ['lww'];\r\n\r\nexport function encodeMapSemantics(semantics: ObjectsApi.ObjectsMapSemantics, client: BaseClient): ObjectsMapSemantics {\r\n  const index = mapSemantics.indexOf(semantics);\r\n  if (index === -1) {\r\n    throw new client.ErrorInfo(`Unrecognized map semantics: ${semantics}`, 40003, 400);\r\n  }\r\n  return index;\r\n}\r\n\r\nexport function decodeMapSemantics(semantics: ObjectsMapSemantics): ObjectsApi.ObjectsMapSemantics {\r\n  return mapSemantics[semantics] ?? 'unknown';\r\n}\r\n\r\n/**\r\n * An ObjectData represents a decoded value in an object on a channel decoded from {@link WireObjectData}.\r\n * @spec OD1\r\n */\r\nexport interface ObjectData {\r\n  /** A reference to another object, used to support composable object structures. Only one value field can be set. */\r\n  objectId?: string; // OD2a\r\n  /** A primitive boolean leaf value in the object graph. Only one value field can be set. */\r\n  boolean?: boolean; // OD2c\r\n  /** A decoded primitive binary leaf value in the object graph. Only one value field can be set. */\r\n  bytes?: Buffer | ArrayBuffer; // OD2d\r\n  /** A primitive number leaf value in the object graph. Only one value field can be set. */\r\n  number?: number; // OD2e\r\n  /** A primitive string leaf value in the object graph. Only one value field can be set. */\r\n  string?: string; // OD2f\r\n  /** A decoded JSON object leaf value in the object graph. Only one value field can be set. */\r\n  json?: ObjectsApi.JsonObject | ObjectsApi.JsonArray; // OD2g\r\n}\r\n\r\n/**\r\n * Extracts the primitive value from an {@link ObjectData}'s typed fields.\r\n * Returns the first non-undefined typed field value, or `undefined` if none is set.\r\n */\r\nexport function getObjectDataPrimitive(data: ObjectData): ObjectsApi.Primitive | undefined {\r\n  return data.boolean ?? data.bytes ?? data.number ?? data.string ?? data.json;\r\n}\r\n\r\n/**\r\n * Converts a {@link Primitive} value into an {@link ObjectData} with the appropriate typed field set.\r\n */\r\nexport function primitiveToObjectData(value: ObjectsApi.Primitive, client: BaseClient): ObjectData {\r\n  if (client.Platform.BufferUtils.isBuffer(value)) return { bytes: value };\r\n  if (typeof value === 'boolean') return { boolean: value };\r\n  if (typeof value === 'number') return { number: value };\r\n  if (typeof value === 'string') return { string: value };\r\n  if (typeof value === 'object' && value !== null) return { json: value };\r\n  return {};\r\n}\r\n\r\n/**\r\n * A WireObjectData represents a value in an object on a channel received from the server.\r\n * @spec OD1\r\n */\r\nexport interface WireObjectData {\r\n  /** A reference to another object, used to support composable object structures. Only one value field can be set. */\r\n  objectId?: string; // OD2a\r\n  /** A primitive boolean leaf value in the object graph. Only one value field can be set. */\r\n  boolean?: boolean; // OD2c\r\n  /** A primitive binary leaf value in the object graph. Only one value field can be set. Represented as a Base64-encoded string in JSON protocol */\r\n  bytes?: Buffer | ArrayBuffer | string; // OD2d\r\n  /** A primitive number leaf value in the object graph. Only one value field can be set. */\r\n  number?: number; // OD2e\r\n  /** A primitive string leaf value in the object graph. Only one value field can be set. */\r\n  string?: string; // OD2f\r\n  /** A primitive JSON-encoded string leaf value in the object graph. Only one value field can be set. */\r\n  json?: string; // OD2g\r\n}\r\n\r\n/**\r\n * An ObjectsMapEntry represents the value at a given key in a Map object.\r\n * @spec OME1\r\n */\r\nexport interface ObjectsMapEntry<TData> {\r\n  /** Indicates whether the map entry has been removed. */\r\n  tombstone?: boolean; // OME2a\r\n  /**\r\n   * The {@link ObjectMessage.serial} value of the last operation that was applied to the map entry.\r\n   *\r\n   * It is optional in a MAP_CREATE operation and might be missing, in which case the client should use a nullish value for it\r\n   * and treat it as the \"earliest possible\" serial for comparison purposes.\r\n   */\r\n  timeserial?: string; // OME2b\r\n  /** A timestamp from the {@link timeserial} field. Only present if {@link tombstone} is `true` */\r\n  serialTimestamp?: number; // OME2d\r\n  /** The data that represents the value of the map entry. */\r\n  data?: TData; // OME2c\r\n}\r\n\r\n/**\r\n * An ObjectsMap object represents a map of key-value pairs.\r\n * @spec OMP1\r\n */\r\nexport interface ObjectsMap<TData> {\r\n  /** The conflict-resolution semantics used by the map object. */\r\n  semantics?: ObjectsMapSemantics; // OMP3a\r\n  /** The map entries, indexed by key. */\r\n  entries?: Record<string, ObjectsMapEntry<TData>>; // OMP3b\r\n  /** The {@link ObjectMessage.serial} value of the last `MAP_CLEAR` operation applied to the map. If no `MAP_CLEAR` has been applied, this field is omitted */\r\n  clearTimeserial?: string; // OMP3c\r\n}\r\n\r\n/**\r\n * An ObjectsCounter object represents an incrementable and decrementable value\r\n * @spec OCN1\r\n */\r\nexport interface ObjectsCounter {\r\n  /** The value of the counter */\r\n  count?: number; // OCN2a\r\n}\r\n\r\n/**\r\n * A MapCreate describes the payload for a MAP_CREATE operation on a map object\r\n * @spec MCR1\r\n */\r\nexport interface MapCreate<TData> {\r\n  /** The conflict-resolution semantics used by the map object. */\r\n  semantics: ObjectsMapSemantics; // MCR2a\r\n  /** The map entries, indexed by key. */\r\n  entries: Record<string, ObjectsMapEntry<TData>>; // MCR2b\r\n}\r\n\r\n/**\r\n * A MapSet describes the payload for a MAP_SET operation on a map object\r\n * @spec MST1\r\n */\r\nexport interface MapSet<TData> {\r\n  /** The key to set. */\r\n  key: string; // MST2a\r\n  /** The value to set. */\r\n  value: TData; // MST2b\r\n}\r\n\r\n/**\r\n * A MapRemove describes the payload for a MAP_REMOVE operation on a map object\r\n * @spec MRM1\r\n */\r\nexport interface MapRemove {\r\n  /** The key to remove. */\r\n  key: string; // MRM2a\r\n}\r\n\r\n/**\r\n * A CounterCreate describes the payload for a COUNTER_CREATE operation on a counter object\r\n * @spec CCR1\r\n */\r\nexport interface CounterCreate {\r\n  /** The initial counter value */\r\n  count: number; // CCR2a\r\n}\r\n\r\n/**\r\n * A CounterInc describes the payload for a COUNTER_INC operation on a counter object\r\n * @spec CIN1\r\n */\r\nexport interface CounterInc {\r\n  /** The value to be added to the counter */\r\n  number: number; // CIN2a\r\n}\r\n\r\n/**\r\n * An ObjectDelete describes the payload for an OBJECT_DELETE operation\r\n * @spec ODE1\r\n */\r\nexport interface ObjectDelete {\r\n  // ODE2 - Empty message, OBJECT_DELETE requires no operation-specific data\r\n}\r\n\r\n/**\r\n * A MapCreateWithObjectId describes the payload for a MAP_CREATE operation with a client-specified object ID\r\n * @spec MCRO1\r\n */\r\nexport interface MapCreateWithObjectId<TData> {\r\n  /**\r\n   * The initial value of the object - an encoded {@link MapCreate} used to create a map represented as a JSON string.\r\n   */\r\n  initialValue: string; // MCRO2a\r\n  /** The nonce used to generate the object ID */\r\n  nonce: string; // MCRO2b\r\n  /**\r\n   * The source {@link MapCreate} from which this was derived. For local use only (message size\r\n   * calculation and apply-on-ACK); not transmitted over the wire.\r\n   * @spec RTO11f18\r\n   * @internal\r\n   */\r\n  _derivedFrom?: MapCreate<TData>;\r\n}\r\n\r\n/**\r\n * A CounterCreateWithObjectId describes the payload for a COUNTER_CREATE operation with a client-specified object ID\r\n * @spec CCRO1\r\n */\r\nexport interface CounterCreateWithObjectId {\r\n  /**\r\n   * The initial value of the object - an encoded {@link CounterCreate} used to create a counter represented as a JSON string.\r\n   */\r\n  initialValue: string; // CCRO2a\r\n  /** The nonce used to generate the object ID */\r\n  nonce: string; // CCRO2b\r\n  /**\r\n   * The source {@link CounterCreate} from which this was derived. For local use only (message size\r\n   * calculation and apply-on-ACK); not transmitted over the wire.\r\n   * @spec RTO12f16\r\n   * @internal\r\n   */\r\n  _derivedFrom?: CounterCreate;\r\n}\r\n\r\n/**\r\n * A MapClear describes the payload for a MAP_CLEAR operation\r\n * @spec MCL1\r\n */\r\nexport interface MapClear {\r\n  // MCL2 - Empty message, MAP_CLEAR requires no operation-specific data\r\n}\r\n\r\n/**\r\n * An ObjectOperation describes an operation to be applied to an object on a channel.\r\n * @spec OOP1\r\n */\r\nexport interface ObjectOperation<TData> {\r\n  /** Defines the operation to be applied to the object. */\r\n  action: ObjectOperationAction; // OOP3a\r\n  /** The object ID of the object on a channel to which the operation should be applied. */\r\n  objectId: string; // OOP3b\r\n\r\n  /**\r\n   * The payload for MAP_CREATE operation when received from the server.\r\n   * Contains the unmarshalled initial value for the Map object.\r\n   */\r\n  mapCreate?: MapCreate<TData>; // OOP3j\r\n  /**\r\n   * The payload for MAP_SET operation.\r\n   */\r\n  mapSet?: MapSet<TData>; // OOP3k\r\n  /**\r\n   * The payload for MAP_REMOVE operation.\r\n   */\r\n  mapRemove?: MapRemove; // OOP3l\r\n  /**\r\n   * The payload for COUNTER_CREATE operation when received from the server.\r\n   * Contains the unmarshalled initial value for the Counter object.\r\n   */\r\n  counterCreate?: CounterCreate; // OOP3m\r\n  /**\r\n   * The payload for COUNTER_INC operation.\r\n   */\r\n  counterInc?: CounterInc; // OOP3n\r\n  /**\r\n   * The payload for OBJECT_DELETE operation.\r\n   */\r\n  objectDelete?: ObjectDelete; // OOP3o\r\n  /**\r\n   * The payload for MAP_CREATE operation when sending to the server.\r\n   * Contains the nonce and JSON-encoded initial value from {@link MapCreate} for object ID verification.\r\n   */\r\n  mapCreateWithObjectId?: MapCreateWithObjectId<TData>; // OOP3p\r\n  /**\r\n   * The payload for COUNTER_CREATE operation when sending to the server.\r\n   * Contains the nonce and JSON-encoded initial value from {@link CounterCreate} for object ID verification.\r\n   */\r\n  counterCreateWithObjectId?: CounterCreateWithObjectId; // OOP3q\r\n  /**\r\n   * The payload for MAP_CLEAR operation.\r\n   */\r\n  mapClear?: MapClear; // OOP3r\r\n}\r\n\r\n/**\r\n * An ObjectState describes the instantaneous state of an object on a channel.\r\n * @spec OST1\r\n */\r\nexport interface ObjectState<TData> {\r\n  /** The identifier of the object. */\r\n  objectId: string; // OST2a\r\n  /** A map of serials keyed by a {@link ObjectMessage.siteCode}, representing the last operations applied to this object */\r\n  siteTimeserials: Record<string, string>; // OST2b\r\n  /** True if the object has been tombstoned. */\r\n  tombstone: boolean; // OST2c\r\n  /**\r\n   * The operation that created the object.\r\n   *\r\n   * Can be missing if create operation for the object is not known at this point.\r\n   */\r\n  createOp?: ObjectOperation<TData>; // OST2d\r\n  /**\r\n   * The data that represents the result of applying all operations to a Map object\r\n   * excluding the initial value from the create operation if it is a Map object type.\r\n   */\r\n  map?: ObjectsMap<TData>; // OST2e\r\n  /**\r\n   * The data that represents the result of applying all operations to a Counter object\r\n   * excluding the initial value from the create operation if it is a Counter object type.\r\n   */\r\n  counter?: ObjectsCounter; // OST2f\r\n}\r\n\r\nfunction encode(\r\n  message: ObjectMessage,\r\n  utils: typeof Utils,\r\n  messageEncoding: typeof MessageEncoding,\r\n  encodeObjectDataFn: EncodeObjectDataFunction<ObjectData>,\r\n): WireObjectMessage;\r\nfunction encode(\r\n  message: WireObjectMessage,\r\n  utils: typeof Utils,\r\n  messageEncoding: typeof MessageEncoding,\r\n  encodeObjectDataFn: EncodeObjectDataFunction<WireObjectData>,\r\n): WireObjectMessage;\r\nfunction encode(\r\n  message: ObjectMessage | WireObjectMessage,\r\n  utils: typeof Utils,\r\n  messageEncoding: typeof MessageEncoding,\r\n  encodeObjectDataFn: EncodeObjectDataFunction<any>,\r\n): WireObjectMessage {\r\n  // deep copy the message to avoid mutating the original one.\r\n  // buffer values won't be correctly copied, so we will need to use the original message when encoding.\r\n  const result = Object.assign(new WireObjectMessage(utils, messageEncoding), copyMsg(message));\r\n\r\n  // encode \"object\" field\r\n  if (message.object?.map?.entries) {\r\n    result.object!.map!.entries = encodeMapEntries(message.object.map.entries, encodeObjectDataFn);\r\n  }\r\n\r\n  if (message.object?.createOp?.mapCreate?.entries) {\r\n    result.object!.createOp!.mapCreate!.entries = encodeMapEntries(\r\n      message.object.createOp.mapCreate.entries,\r\n      encodeObjectDataFn,\r\n    );\r\n  }\r\n\r\n  // encode \"operation\" field\r\n  if (message.operation?.mapCreate?.entries) {\r\n    result.operation!.mapCreate!.entries = encodeMapEntries(message.operation.mapCreate.entries, encodeObjectDataFn);\r\n  }\r\n\r\n  if (message.operation?.mapSet?.value) {\r\n    result.operation!.mapSet!.value = encodeObjectData(message.operation.mapSet.value, encodeObjectDataFn);\r\n  }\r\n\r\n  // encode _derivedFrom entries on *CreateWithObjectId - these hold ObjectData that needs\r\n  // encoding to WireObjectData for correct message size calculation.\r\n  if (message.operation?.mapCreateWithObjectId?._derivedFrom?.entries) {\r\n    result.operation!.mapCreateWithObjectId!._derivedFrom!.entries = encodeMapEntries(\r\n      message.operation.mapCreateWithObjectId._derivedFrom.entries,\r\n      encodeObjectDataFn,\r\n    );\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\nfunction encodeMapEntries(\r\n  mapEntries: Record<string, ObjectsMapEntry<ObjectData | WireObjectData>>,\r\n  encodeFn: EncodeObjectDataFunction,\r\n): Record<string, ObjectsMapEntry<WireObjectData>> {\r\n  return Object.entries(mapEntries).reduce(\r\n    (acc, v) => {\r\n      const [key, entry] = v;\r\n      const encodedData = entry.data ? encodeObjectData(entry.data, encodeFn) : undefined;\r\n      acc[key] = {\r\n        ...entry,\r\n        data: encodedData,\r\n      };\r\n      return acc;\r\n    },\r\n    {} as Record<string, ObjectsMapEntry<WireObjectData>>,\r\n  );\r\n}\r\n\r\n/** @spec OD4 */\r\nfunction encodeObjectData(data: ObjectData | WireObjectData, encodeFn: EncodeObjectDataFunction): WireObjectData {\r\n  const encodedData = encodeFn(data);\r\n  return encodedData;\r\n}\r\n\r\n/**\r\n * Encodes a partial {@link ObjectOperation} for wire transmission.\r\n *\r\n * This is used in multiple contexts:\r\n * - During realtime *_CREATE operations to produce the wire-safe representation that will be\r\n *   JSON-stringified and set as the `initialValue` field in\r\n *   {@link MapCreateWithObjectId} or {@link CounterCreateWithObjectId}.\r\n * - In the REST SDK to get an encoded initial value for an object to generate\r\n *   a client-side object ID.\r\n * - In the REST SDK publish path to encode user-provided operation data for transmission.\r\n *\r\n * The provided operation may contain user-provided data that requires encoding\r\n * (e.g. buffers must be encoded for JSON wire format).\r\n */\r\nexport function encodePartialObjectOperationForWire(\r\n  operation: Partial<ObjectOperation<ObjectData>>,\r\n  client: BaseClient,\r\n  format: Utils.Format,\r\n): Partial<ObjectOperation<WireObjectData>> {\r\n  const msg = ObjectMessage.fromValues(\r\n    // cast to ObjectOperation here, even though provided operation may lack some properties\r\n    // that are usually present on the ObjectOperation.\r\n    // this ObjectMessage instance is only used to get the encoded body,\r\n    // so it's ok for the operation field to be incomplete in this context.\r\n    // doing the type assertion here avoids the need to define a separate ObjectMessage\r\n    // type that supports a fully optional ObjectOperation.\r\n    { operation: operation as ObjectOperation<ObjectData> },\r\n    client.Utils,\r\n    client.MessageEncoding,\r\n  );\r\n  const wireMsg = msg.encode();\r\n\r\n  // get the encoded operation that is safe to be sent over the wire.\r\n  const { operation: encodedOperation } = wireMsg.encodeForWire(format);\r\n  return encodedOperation!;\r\n}\r\n\r\n/** @spec OD5 */\r\nexport function decodeWireObjectData(\r\n  wireData: WireObjectData,\r\n  client: BaseClient,\r\n  format: Utils.Format | undefined,\r\n): ObjectData {\r\n  try {\r\n    if (wireData.objectId != null) {\r\n      return { objectId: wireData.objectId };\r\n    }\r\n\r\n    if (wireData.bytes != null) {\r\n      const decodedBytes =\r\n        format === 'msgpack'\r\n          ? // OD5a1 - connection is using msgpack protocol, bytes are already a buffer\r\n            (wireData.bytes as Buffer | ArrayBuffer)\r\n          : // OD5b2 - connection is using JSON protocol, Base64-decode bytes value\r\n            client.Platform.BufferUtils.base64Decode(String(wireData.bytes));\r\n      return { bytes: decodedBytes };\r\n    }\r\n\r\n    if (wireData.json != null) {\r\n      return { json: JSON.parse(wireData.json) }; // OD5a2, OD5b3\r\n    }\r\n\r\n    if (wireData.boolean != null) {\r\n      return { boolean: wireData.boolean };\r\n    }\r\n\r\n    if (wireData.number != null) {\r\n      return { number: wireData.number };\r\n    }\r\n\r\n    if (wireData.string != null) {\r\n      return { string: wireData.string };\r\n    }\r\n\r\n    // unrecognized ObjectData shape - pass through as-is so we don't lose any data\r\n    client.Logger.logAction(\r\n      client.logger,\r\n      client.Logger.LOG_MINOR,\r\n      'decodeWireObjectData()',\r\n      'Unrecognized wire ObjectData shape, keys: ' + Object.keys(wireData).join(', '),\r\n    );\r\n    return { ...wireData } as ObjectData;\r\n  } catch (error) {\r\n    client.Logger.logAction(\r\n      client.logger,\r\n      client.Logger.LOG_ERROR,\r\n      'decodeWireObjectData()',\r\n      client.Utils.inspectError(error),\r\n    );\r\n    // object data decoding has failed, return the data as is.\r\n    return {\r\n      ...wireData,\r\n    } as ObjectData;\r\n  }\r\n}\r\n\r\nfunction strMsg(msg: any, className: string) {\r\n  let result = '[' + className;\r\n\r\n  for (const attr in msg) {\r\n    if (msg[attr] === undefined || attr === '_utils' || attr === '_messageEncoding') {\r\n      continue;\r\n    }\r\n\r\n    if (attr === 'operation' || attr === 'object' || attr === 'extras') {\r\n      result += `; ${attr}=${JSON.stringify(msg[attr])}`;\r\n    } else {\r\n      result += `; ${attr}=${msg[attr]}`;\r\n    }\r\n  }\r\n\r\n  result += ']';\r\n  return result;\r\n}\r\n\r\n/**\r\n * Deep copy public properties of an object message, using `JSON.parse(JSON.stringify(object))` for nested object fields like `operation` and `object`.\r\n *\r\n * Important: Buffer instances are not copied correctly using `JSON.parse(JSON.stringify(object))`, as they lose their type and become plain objects.\r\n * If you need access to the original Buffer values, use the original message instance instead.\r\n */\r\n\r\nfunction copyMsg(\r\n  msg: Utils.Properties<ObjectMessage | WireObjectMessage>,\r\n): Utils.Properties<ObjectMessage | WireObjectMessage> {\r\n  const result: Utils.Properties<ObjectMessage | WireObjectMessage> = {\r\n    id: msg.id,\r\n    clientId: msg.clientId,\r\n    connectionId: msg.connectionId,\r\n    timestamp: msg.timestamp,\r\n    serial: msg.serial,\r\n    serialTimestamp: msg.serialTimestamp,\r\n    siteCode: msg.siteCode,\r\n  };\r\n\r\n  if (msg.operation) {\r\n    result.operation = JSON.parse(JSON.stringify(msg.operation));\r\n  }\r\n  if (msg.object) {\r\n    result.object = JSON.parse(JSON.stringify(msg.object));\r\n  }\r\n  if (msg.extras) {\r\n    result.extras = JSON.parse(JSON.stringify(msg.extras));\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\nfunction toUserFacingObjectData(data: ObjectData): ObjectsApi.ObjectData {\r\n  if (data.objectId != null) {\r\n    return { objectId: data.objectId };\r\n  }\r\n\r\n  return {\r\n    ...data,\r\n    // deprecated field for backwards compatibility\r\n    value: getObjectDataPrimitive(data),\r\n  };\r\n}\r\n\r\nfunction toUserFacingMapEntry(entry: ObjectsMapEntry<ObjectData>): ObjectsApi.ObjectsMapEntry {\r\n  return {\r\n    ...entry,\r\n    data: entry.data ? toUserFacingObjectData(entry.data) : undefined,\r\n  };\r\n}\r\n\r\nfunction toUserFacingObjectOperation(operation: ObjectOperation<ObjectData>): ObjectsApi.ObjectOperation {\r\n  const { mapSet: internalMapSet, mapRemove, counterInc, objectDelete, mapClear } = operation;\r\n\r\n  // resolve *Create from direct property or from *CreateWithObjectId._derivedFrom\r\n  const internalMapCreate = operation.mapCreate ?? operation.mapCreateWithObjectId?._derivedFrom;\r\n  const counterCreate = operation.counterCreate ?? operation.counterCreateWithObjectId?._derivedFrom;\r\n\r\n  let mapCreate: ObjectsApi.MapCreate | undefined;\r\n  if (internalMapCreate) {\r\n    mapCreate = {\r\n      ...internalMapCreate,\r\n      semantics: decodeMapSemantics(internalMapCreate.semantics),\r\n      entries: Object.fromEntries(\r\n        Object.entries(internalMapCreate.entries).map(([key, entry]) => [key, toUserFacingMapEntry(entry)]),\r\n      ),\r\n    };\r\n  }\r\n\r\n  let mapSet: ObjectsApi.MapSet | undefined;\r\n  if (internalMapSet) {\r\n    mapSet = {\r\n      ...internalMapSet,\r\n      value: toUserFacingObjectData(internalMapSet.value),\r\n    };\r\n  }\r\n\r\n  // ObjectOperation deprecated fields for backwards compatibility\r\n  let mapOp: ObjectsApi.ObjectsMapOp | undefined;\r\n  if (mapSet) {\r\n    mapOp = {\r\n      key: mapSet.key,\r\n      data: mapSet.value,\r\n    };\r\n  } else if (mapRemove) {\r\n    mapOp = { key: mapRemove.key };\r\n  }\r\n\r\n  let counterOp: ObjectsApi.ObjectsCounterOp | undefined;\r\n  if (counterInc) {\r\n    counterOp = { amount: counterInc.number };\r\n  }\r\n\r\n  return {\r\n    action: decodeObjectOperationAction(operation.action),\r\n    objectId: operation.objectId,\r\n    mapCreate,\r\n    mapSet,\r\n    mapRemove,\r\n    counterCreate,\r\n    counterInc,\r\n    objectDelete,\r\n    mapClear,\r\n    // deprecated fields\r\n    mapOp,\r\n    counterOp,\r\n    map: mapCreate,\r\n    counter: counterCreate,\r\n  };\r\n}\r\n\r\n/**\r\n * A decoded {@link WireObjectMessage} message\r\n * @spec OM1\r\n * @internal\r\n */\r\nexport class ObjectMessage {\r\n  id?: string; // OM2a\r\n  clientId?: string; // OM2b\r\n  connectionId?: string; // OM2c\r\n  extras?: any; // OM2d\r\n  timestamp?: number; // OM2e\r\n  /**\r\n   * Describes an operation to be applied to an object.\r\n   *\r\n   * Mutually exclusive with the `object` field. This field is only set on object messages if the `action` field of the `ProtocolMessage` encapsulating it is `OBJECT`.\r\n   */\r\n  operation?: ObjectOperation<ObjectData>; // OM2f\r\n  /**\r\n   * Describes the instantaneous state of an object.\r\n   *\r\n   * Mutually exclusive with the `operation` field. This field is only set on object messages if the `action` field of the `ProtocolMessage` encapsulating it is `OBJECT_SYNC`.\r\n   */\r\n  object?: ObjectState<ObjectData>; // OM2g\r\n  /** An opaque string that uniquely identifies this object message. */\r\n  serial?: string; // OM2h\r\n  /** A timestamp from the {@link serial} field. */\r\n  serialTimestamp?: number; // OM2j\r\n  /** An opaque string used as a key to update the map of serial values on an object. */\r\n  siteCode?: string; // OM2i\r\n\r\n  constructor(\r\n    private _utils: typeof Utils,\r\n    private _messageEncoding: typeof MessageEncoding,\r\n  ) {}\r\n\r\n  static fromValues(\r\n    values: Utils.Properties<ObjectMessage>,\r\n    utils: typeof Utils,\r\n    messageEncoding: typeof MessageEncoding,\r\n  ): ObjectMessage {\r\n    return Object.assign(new ObjectMessage(utils, messageEncoding), values);\r\n  }\r\n\r\n  static fromValuesArray(\r\n    values: Utils.Properties<ObjectMessage>[],\r\n    utils: typeof Utils,\r\n    messageEncoding: typeof MessageEncoding,\r\n  ): ObjectMessage[] {\r\n    return values.map((x) => ObjectMessage.fromValues(x, utils, messageEncoding));\r\n  }\r\n\r\n  /**\r\n   * Protocol agnostic encoding of this ObjectMessage. Returns a new {@link WireObjectMessage} instance.\r\n   *\r\n   * Uses encoding functions from regular `Message` processing.\r\n   *\r\n   * @spec OM4\r\n   */\r\n  encode(): WireObjectMessage {\r\n    const encodeObjectDataFn: EncodeObjectDataFunction<ObjectData> = (data) => {\r\n      const encodedObjectData: WireObjectData = {\r\n        // bytes encoding happens later when WireObjectMessage is encoded for wire transmission, so we just copy all fields except json for now.\r\n        // OD4c1, OD4d1, OD4c3, OD4d3, OD4c4, OD4d4\r\n        ...data,\r\n        json: data.json != null ? JSON.stringify(data.json) : undefined, // OD4c5, OD4d5\r\n      };\r\n\r\n      return encodedObjectData;\r\n    };\r\n\r\n    return encode(this, this._utils, this._messageEncoding, encodeObjectDataFn);\r\n  }\r\n\r\n  toString(): string {\r\n    return strMsg(this, 'ObjectMessage');\r\n  }\r\n\r\n  isOperationMessage(): boolean {\r\n    return this.operation != null;\r\n  }\r\n\r\n  isSyncMessage(): boolean {\r\n    return this.object != null;\r\n  }\r\n\r\n  toUserFacingMessage(channel: RealtimeChannel): ObjectsApi.ObjectMessage {\r\n    return {\r\n      id: this.id,\r\n      clientId: this.clientId,\r\n      connectionId: this.connectionId,\r\n      timestamp: this.timestamp,\r\n      channel: channel.name,\r\n      // we expose only operation messages to users, so operation field is always present\r\n      operation: toUserFacingObjectOperation(this.operation!),\r\n      serial: this.serial,\r\n      serialTimestamp: this.serialTimestamp,\r\n      siteCode: this.siteCode,\r\n      extras: this.extras,\r\n    };\r\n  }\r\n}\r\n\r\n/**\r\n * An individual object message to be sent or received via the Ably Realtime service.\r\n * @spec OM1\r\n * @internal\r\n */\r\nexport class WireObjectMessage {\r\n  id?: string; // OM2a\r\n  clientId?: string; // OM2b\r\n  connectionId?: string; // OM2c\r\n  extras?: any; // OM2d\r\n  timestamp?: number; // OM2e\r\n  /**\r\n   * Describes an operation to be applied to an object.\r\n   *\r\n   * Mutually exclusive with the `object` field. This field is only set on object messages if the `action` field of the `ProtocolMessage` encapsulating it is `OBJECT`.\r\n   */\r\n  operation?: ObjectOperation<WireObjectData>; // OM2f\r\n  /**\r\n   * Describes the instantaneous state of an object.\r\n   *\r\n   * Mutually exclusive with the `operation` field. This field is only set on object messages if the `action` field of the `ProtocolMessage` encapsulating it is `OBJECT_SYNC`.\r\n   */\r\n  object?: ObjectState<WireObjectData>; // OM2g\r\n  /** An opaque string that uniquely identifies this object message. */\r\n  serial?: string; // OM2h\r\n  /** A timestamp from the {@link serial} field. */\r\n  serialTimestamp?: number; // OM2j\r\n  /** An opaque string used as a key to update the map of serial values on an object. */\r\n  siteCode?: string; // OM2i\r\n\r\n  constructor(\r\n    private _utils: typeof Utils,\r\n    private _messageEncoding: typeof MessageEncoding,\r\n  ) {}\r\n\r\n  static fromValues(\r\n    values: Utils.Properties<WireObjectMessage>,\r\n    utils: typeof Utils,\r\n    messageEncoding: typeof MessageEncoding,\r\n  ): WireObjectMessage {\r\n    return Object.assign(new WireObjectMessage(utils, messageEncoding), values);\r\n  }\r\n\r\n  static fromValuesArray(\r\n    values: Utils.Properties<WireObjectMessage>[],\r\n    utils: typeof Utils,\r\n    messageEncoding: typeof MessageEncoding,\r\n  ): WireObjectMessage[] {\r\n    return values.map((x) => WireObjectMessage.fromValues(x, utils, messageEncoding));\r\n  }\r\n\r\n  /**\r\n   * Encodes WireObjectMessage for wire transmission. Does not mutate the provided WireObjectMessage.\r\n   *\r\n   * Uses encoding functions from regular `Message` processing.\r\n   */\r\n  encodeForWire(format: Utils.Format): WireObjectMessage {\r\n    const encodeObjectDataFn: EncodeObjectDataFunction<WireObjectData> = (data) => {\r\n      if (data.bytes != null) {\r\n        // OD4c2, OD4d2\r\n        const result = this._messageEncoding.encodeDataForWire(data.bytes, null, format);\r\n        // no need to set the encoding\r\n        return { ...data, bytes: result.data };\r\n      }\r\n\r\n      return { ...data };\r\n    };\r\n\r\n    const result = encode(this, this._utils, this._messageEncoding, encodeObjectDataFn);\r\n\r\n    // Strip _derivedFrom from *CreateWithObjectId \u2014 it is for local use only and must not be sent over the wire.\r\n    if (result.operation?.mapCreateWithObjectId) {\r\n      delete result.operation.mapCreateWithObjectId._derivedFrom;\r\n    }\r\n    if (result.operation?.counterCreateWithObjectId) {\r\n      delete result.operation.counterCreateWithObjectId._derivedFrom;\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * Decodes this WireObjectMessage and returns a new {@link ObjectMessage} instance.\r\n   *\r\n   * Format is used to decode the bytes value as it's implicitly encoded depending on the protocol used:\r\n   * - json: bytes are Base64-encoded string\r\n   * - msgpack: bytes have a binary representation and don't need to be decoded\r\n   *\r\n   * @spec OM5\r\n   */\r\n  decode(client: BaseClient, format: Utils.Format | undefined): ObjectMessage {\r\n    // deep copy the message to avoid mutating the original one.\r\n    // buffer values won't be correctly copied, so we will need to use the original message when decoding.\r\n    const result = Object.assign(new ObjectMessage(this._utils, this._messageEncoding), copyMsg(this));\r\n\r\n    try {\r\n      // decode \"object\" field\r\n      if (this.object?.map?.entries) {\r\n        result.object!.map!.entries = this._decodeMapEntries(this.object.map.entries, client, format);\r\n      }\r\n\r\n      if (this.object?.createOp?.mapCreate?.entries) {\r\n        result.object!.createOp!.mapCreate!.entries = this._decodeMapEntries(\r\n          this.object.createOp.mapCreate.entries,\r\n          client,\r\n          format,\r\n        );\r\n      }\r\n\r\n      // decode \"operation\" field\r\n      if (this.operation?.mapCreate?.entries) {\r\n        result.operation!.mapCreate!.entries = this._decodeMapEntries(this.operation.mapCreate.entries, client, format);\r\n      }\r\n\r\n      if (this.operation?.mapSet?.value) {\r\n        result.operation!.mapSet!.value = decodeWireObjectData(this.operation.mapSet.value, client, format);\r\n      }\r\n    } catch (error) {\r\n      client.Logger.logAction(\r\n        client.logger,\r\n        client.Logger.LOG_ERROR,\r\n        'WireObjectMessage.decode()',\r\n        this._utils.inspectError(error),\r\n      );\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * Overload toJSON() to intercept JSON.stringify().\r\n   *\r\n   * This will prepare the message to be transmitted over the wire to Ably.\r\n   * It will encode the data payload according to the wire protocol used on the client.\r\n   */\r\n  toJSON() {\r\n    // we can infer the format used by client by inspecting with what arguments this method was called.\r\n    // if JSON protocol is being used, the JSON.stringify() will be called and this toJSON() method will have a non-empty arguments list.\r\n    // MSGPack protocol implementation also calls toJSON(), but with an empty arguments list.\r\n    const format = arguments.length > 0 ? this._utils.Format.json : this._utils.Format.msgpack;\r\n    const { _utils, _messageEncoding, ...publicProps } = this.encodeForWire(format);\r\n    return publicProps;\r\n  }\r\n\r\n  toString(): string {\r\n    return strMsg(this, 'WireObjectMessage');\r\n  }\r\n\r\n  /** @spec OM3 */\r\n  getMessageSize(): number {\r\n    let size = 0;\r\n\r\n    // OM3a\r\n    size += this.clientId?.length ?? 0; // OM3f\r\n    if (this.operation) {\r\n      size += this._getObjectOperationSize(this.operation); // OM3b\r\n    }\r\n    if (this.object) {\r\n      size += this._getObjectStateSize(this.object); // OM3c\r\n    }\r\n    if (this.extras) {\r\n      size += JSON.stringify(this.extras).length; // OM3d\r\n    }\r\n\r\n    return size;\r\n  }\r\n\r\n  /** @spec OOP4 */\r\n  private _getObjectOperationSize(operation: ObjectOperation<WireObjectData>): number {\r\n    let size = 0;\r\n\r\n    // OOP4h - map create size: from mapCreate if present (OOP4h1), else from mapCreateWithObjectId._derivedFrom (OOP4h2)\r\n    const mapCreate = operation.mapCreate ?? operation.mapCreateWithObjectId?._derivedFrom;\r\n    if (mapCreate) {\r\n      size += this._getMapCreateSize(mapCreate);\r\n    }\r\n    if (operation.mapSet) {\r\n      size += this._getMapSetSize(operation.mapSet); // OOP4i\r\n    }\r\n    if (operation.mapRemove) {\r\n      size += this._getMapRemoveSize(operation.mapRemove); // OOP4j\r\n    }\r\n    // OOP4k - counter create size: from counterCreate if present (OOP4k1), else from counterCreateWithObjectId._derivedFrom (OOP4k2)\r\n    const counterCreate = operation.counterCreate ?? operation.counterCreateWithObjectId?._derivedFrom;\r\n    if (counterCreate) {\r\n      size += this._getCounterCreateSize(counterCreate);\r\n    }\r\n    if (operation.counterInc) {\r\n      size += this._getCounterIncSize(operation.counterInc); // OOP4l\r\n    }\r\n\r\n    return size;\r\n  }\r\n\r\n  /** @spec OST3 */\r\n  private _getObjectStateSize(obj: ObjectState<WireObjectData>): number {\r\n    let size = 0;\r\n\r\n    // OST3a\r\n    if (obj.map) {\r\n      size += this._getObjectMapSize(obj.map); // OST3b\r\n    }\r\n    if (obj.counter) {\r\n      size += this._getObjectCounterSize(obj.counter); // OST3c\r\n    }\r\n    if (obj.createOp) {\r\n      size += this._getObjectOperationSize(obj.createOp); // OST3d\r\n    }\r\n\r\n    return size;\r\n  }\r\n\r\n  /** @spec OMP4 */\r\n  private _getObjectMapSize(map: ObjectsMap<WireObjectData>): number {\r\n    let size = 0;\r\n\r\n    // OMP4a\r\n    Object.entries(map.entries ?? {}).forEach(([key, entry]) => {\r\n      size += key?.length ?? 0; // OMP4a1\r\n      if (entry) {\r\n        size += this._getMapEntrySize(entry); // OMP4a2\r\n      }\r\n    });\r\n\r\n    return size;\r\n  }\r\n\r\n  /** @spec OCN3 */\r\n  private _getObjectCounterSize(counter: ObjectsCounter): number {\r\n    // OCN3b\r\n    if (counter.count == null) {\r\n      return 0;\r\n    }\r\n\r\n    // OCN3a\r\n    return 8;\r\n  }\r\n\r\n  /** @spec OME3 */\r\n  private _getMapEntrySize(entry: ObjectsMapEntry<WireObjectData>): number {\r\n    let size = 0;\r\n\r\n    // OME3a\r\n    if (entry.data) {\r\n      size += this._getObjectDataSize(entry.data); // OME3b\r\n    }\r\n\r\n    return size;\r\n  }\r\n\r\n  /** @spec MCR3 */\r\n  private _getMapCreateSize(mapCreate: MapCreate<WireObjectData>): number {\r\n    let size = 0;\r\n\r\n    // MCR3a\r\n    Object.entries(mapCreate.entries ?? {}).forEach(([key, entry]) => {\r\n      size += key?.length ?? 0; // MCR3a1\r\n      if (entry) {\r\n        size += this._getMapEntrySize(entry); // MCR3a2\r\n      }\r\n    });\r\n\r\n    return size;\r\n  }\r\n\r\n  /** @spec MST3 */\r\n  private _getMapSetSize(mapSet: MapSet<WireObjectData>): number {\r\n    let size = 0;\r\n\r\n    size += mapSet.key?.length ?? 0; // MST3c\r\n    if (mapSet.value) {\r\n      size += this._getObjectDataSize(mapSet.value); // MST3b\r\n    }\r\n\r\n    return size;\r\n  }\r\n\r\n  /** @spec MRM3 */\r\n  private _getMapRemoveSize(mapRemove: MapRemove): number {\r\n    return mapRemove.key.length ?? 0; // MRM3a\r\n  }\r\n\r\n  /** @spec CCR3 */\r\n  private _getCounterCreateSize(counterCreate: CounterCreate): number {\r\n    if (counterCreate.count == null) {\r\n      return 0; // CCR3b\r\n    }\r\n\r\n    return 8; // CCR3a\r\n  }\r\n\r\n  /** @spec CIN3 */\r\n  private _getCounterIncSize(counterInc: CounterInc): number {\r\n    if (counterInc.number == null) {\r\n      return 0; // CIN3b\r\n    }\r\n\r\n    return 8; // CIN3a\r\n  }\r\n\r\n  /** @spec OD3 */\r\n  private _getObjectDataSize(data: WireObjectData): number {\r\n    let size = 0;\r\n\r\n    // OD3a\r\n    if (data.boolean != null) {\r\n      size += this._utils.dataSizeBytes(data.boolean); // OD3b\r\n    }\r\n    if (data.bytes != null) {\r\n      size += this._utils.dataSizeBytes(data.bytes); // OD3c\r\n    }\r\n    if (data.number != null) {\r\n      size += this._utils.dataSizeBytes(data.number); // OD3d\r\n    }\r\n    if (data.string != null) {\r\n      size += this._utils.dataSizeBytes(data.string); // OD3e\r\n    }\r\n    if (data.json != null) {\r\n      size += this._utils.dataSizeBytes(data.json);\r\n    }\r\n\r\n    return size;\r\n  }\r\n\r\n  private _decodeMapEntries(\r\n    mapEntries: Record<string, ObjectsMapEntry<WireObjectData>>,\r\n    client: BaseClient,\r\n    format: Utils.Format | undefined,\r\n  ): Record<string, ObjectsMapEntry<ObjectData>> {\r\n    return Object.entries(mapEntries).reduce(\r\n      (acc, v) => {\r\n        const [key, entry] = v;\r\n        const decodedData = entry.data ? decodeWireObjectData(entry.data, client, format) : undefined;\r\n        acc[key] = {\r\n          ...entry,\r\n          data: decodedData,\r\n        };\r\n        return acc;\r\n      },\r\n      {} as Record<string, ObjectsMapEntry<ObjectData>>,\r\n    );\r\n  }\r\n}\r\n", "import { __livetype } from '../../../ably';\r\nimport { LiveCounter } from '../../../liveobjects';\r\nimport { ObjectId } from './objectid';\r\nimport {\r\n  CounterCreate,\r\n  encodePartialObjectOperationForWire,\r\n  ObjectData,\r\n  ObjectMessage,\r\n  ObjectOperation,\r\n  ObjectOperationAction,\r\n} from './objectmessage';\r\nimport { RealtimeObject } from './realtimeobject';\r\n\r\n/**\r\n * A value type class that serves as a simple container for LiveCounter data.\r\n * Contains sufficient information for the client to produce a COUNTER_CREATE operation\r\n * for the LiveCounter object.\r\n *\r\n * Properties of this class are immutable after construction and the instance\r\n * will be frozen to prevent mutation.\r\n */\r\nexport class LiveCounterValueType implements LiveCounter {\r\n  declare readonly [__livetype]: 'LiveCounter'; // type-only, unique symbol to satisfy branded interfaces, no JS emitted\r\n  private readonly _livetype = 'LiveCounter'; // use a runtime property to provide a reliable cross-bundle type identification instead of `instanceof` operator\r\n  private readonly _count: number;\r\n\r\n  private constructor(count: number) {\r\n    this._count = count;\r\n    Object.freeze(this);\r\n  }\r\n\r\n  static create(initialCount: number = 0): LiveCounter {\r\n    // We can't directly import the ErrorInfo class from the core library into the plugin (as this would bloat the plugin size),\r\n    // and, since we're in a user-facing static method, we can't expect a user to pass a client library instance, as this would make the API ugly.\r\n    // Since we can't use ErrorInfo here, we won't do any validation at this step; instead, validation will happen in the mutation methods\r\n    // when we try to create this object.\r\n\r\n    return new LiveCounterValueType(initialCount);\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static instanceof(value: unknown): value is LiveCounterValueType {\r\n    return typeof value === 'object' && value !== null && (value as LiveCounterValueType)._livetype === 'LiveCounter';\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static async createCounterCreateMessage(\r\n    realtimeObject: RealtimeObject,\r\n    value: LiveCounterValueType,\r\n  ): Promise<ObjectMessage> {\r\n    const client = realtimeObject.getClient();\r\n    const count = value._count;\r\n\r\n    if (count !== undefined && (typeof count !== 'number' || !Number.isFinite(count))) {\r\n      throw new client.ErrorInfo('Counter value should be a valid number', 40003, 400);\r\n    }\r\n\r\n    const counterCreate = LiveCounterValueType._getCounterCreate(count); // RTO12f12\r\n    const { counterCreate: encodedCounterCreate } = encodePartialObjectOperationForWire(\r\n      { counterCreate },\r\n      client,\r\n      client.Utils.Format.json,\r\n    );\r\n    const initialValueJSONString = JSON.stringify(encodedCounterCreate); // RTO12f13\r\n    const nonce = await ObjectId.generateNonce(client); // RTO12f4\r\n    const msTimestamp = await client.getTimestamp(true); // RTO12f5\r\n\r\n    // RTO12f6\r\n    const objectId = ObjectId.fromInitialValue(\r\n      client.Platform,\r\n      'counter',\r\n      initialValueJSONString,\r\n      nonce,\r\n      msTimestamp,\r\n    ).toString();\r\n\r\n    const msg = ObjectMessage.fromValues(\r\n      {\r\n        operation: {\r\n          action: ObjectOperationAction.COUNTER_CREATE, // RTO12f7\r\n          objectId, // RTO12f8\r\n          counterCreateWithObjectId: {\r\n            nonce, // RTO12f14\r\n            initialValue: initialValueJSONString, // RTO12f15\r\n            // RTO12f16 - retain the source CounterCreate for local use (size calculation and apply-on-ACK)\r\n            _derivedFrom: counterCreate,\r\n          },\r\n        } as ObjectOperation<ObjectData>,\r\n      },\r\n      client.Utils,\r\n      client.MessageEncoding,\r\n    );\r\n\r\n    return msg;\r\n  }\r\n\r\n  private static _getCounterCreate(count?: number): CounterCreate {\r\n    return {\r\n      count: count ?? 0, // RTO12f12a, RTO12f12b\r\n    };\r\n  }\r\n}\r\n", "import { dequal } from 'dequal';\r\n\r\nimport { __livetype } from '../../../ably';\r\nimport {\r\n  CompactedJsonValue,\r\n  CompactedValue,\r\n  LiveMap as PublicLiveMap,\r\n  LiveObject as PublicLiveObject,\r\n  Primitive,\r\n  Value,\r\n} from '../../../liveobjects';\r\nimport { LiveCounter } from './livecounter';\r\nimport { LiveCounterValueType } from './livecountervaluetype';\r\nimport { LiveMapValueType } from './livemapvaluetype';\r\nimport { LiveObject, LiveObjectData, LiveObjectUpdate, LiveObjectUpdateNoop } from './liveobject';\r\nimport {\r\n  getObjectDataPrimitive,\r\n  MapRemove,\r\n  MapSet,\r\n  ObjectData,\r\n  ObjectMessage,\r\n  ObjectOperation,\r\n  ObjectOperationAction,\r\n  ObjectsMapEntry,\r\n  ObjectsMapSemantics,\r\n  primitiveToObjectData,\r\n} from './objectmessage';\r\nimport { ObjectsOperationSource, RealtimeObject } from './realtimeobject';\r\n\r\nexport interface ObjectIdObjectData {\r\n  /** A reference to another object, used to support composable object structures. */\r\n  objectId: string;\r\n}\r\n\r\nexport type LiveMapObjectData = ObjectIdObjectData | Omit<ObjectData, 'objectId'>;\r\n\r\nexport interface LiveMapEntry {\r\n  tombstone: boolean;\r\n  tombstonedAt: number | undefined;\r\n  timeserial: string | undefined;\r\n  data: LiveMapObjectData | undefined;\r\n}\r\n\r\nexport interface LiveMapData extends LiveObjectData {\r\n  data: Map<string, LiveMapEntry>; // RTLM3\r\n}\r\n\r\nexport interface LiveMapUpdate<T extends Record<string, Value>> extends LiveObjectUpdate {\r\n  update: { [keyName in keyof T & string]?: 'updated' | 'removed' };\r\n  _type: 'LiveMapUpdate';\r\n}\r\n\r\n/** @spec RTLM1, RTLM2 */\r\nexport class LiveMap<T extends Record<string, Value> = Record<string, Value>>\r\n  extends LiveObject<LiveMapData, LiveMapUpdate<T>>\r\n  implements PublicLiveMap<T>\r\n{\r\n  declare readonly [__livetype]: 'LiveMap'; // type-only, unique symbol to satisfy branded interfaces, no JS emitted\r\n  private _clearTimeserial?: string; // RTLM25\r\n\r\n  constructor(\r\n    realtimeObject: RealtimeObject,\r\n    private _semantics: ObjectsMapSemantics,\r\n    objectId: string,\r\n  ) {\r\n    super(realtimeObject, objectId);\r\n  }\r\n\r\n  /**\r\n   * Returns a {@link LiveMap} instance with an empty map data.\r\n   *\r\n   * @internal\r\n   * @spec RTLM4\r\n   */\r\n  static zeroValue(realtimeObject: RealtimeObject, objectId: string): LiveMap {\r\n    return new LiveMap(realtimeObject, ObjectsMapSemantics.LWW, objectId);\r\n  }\r\n\r\n  /**\r\n   * Returns a {@link LiveMap} instance based on the provided object state.\r\n   * The provided object state must hold a valid map object data.\r\n   *\r\n   * @internal\r\n   */\r\n  static fromObjectState(realtimeObject: RealtimeObject, objectMessage: ObjectMessage): LiveMap {\r\n    const obj = new LiveMap(realtimeObject, objectMessage.object!.map!.semantics!, objectMessage.object!.objectId);\r\n    obj.overrideWithObjectState(objectMessage);\r\n    return obj;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static async createMapSetMessage(\r\n    realtimeObject: RealtimeObject,\r\n    objectId: string,\r\n    key: string,\r\n    value: Value,\r\n  ): Promise<ObjectMessage[]> {\r\n    const client = realtimeObject.getClient();\r\n\r\n    LiveMap.validateKeyValue(realtimeObject, key, value);\r\n\r\n    let objectData: LiveMapObjectData;\r\n    let createValueTypesMessages: ObjectMessage[] = [];\r\n\r\n    if (LiveCounterValueType.instanceof(value)) {\r\n      const counterCreateMsg = await LiveCounterValueType.createCounterCreateMessage(realtimeObject, value);\r\n      createValueTypesMessages = [counterCreateMsg];\r\n\r\n      const typedObjectData: ObjectIdObjectData = { objectId: counterCreateMsg.operation?.objectId! };\r\n      objectData = typedObjectData;\r\n    } else if (LiveMapValueType.instanceof(value)) {\r\n      const { mapCreateMsg, nestedObjectsCreateMsgs } = await LiveMapValueType.createMapCreateMessage(\r\n        realtimeObject,\r\n        value,\r\n      );\r\n      createValueTypesMessages = [...nestedObjectsCreateMsgs, mapCreateMsg];\r\n\r\n      const typedObjectData: ObjectIdObjectData = { objectId: mapCreateMsg.operation?.objectId! };\r\n      objectData = typedObjectData;\r\n    } else {\r\n      // RTLM20e7b, RTLM20e7c, RTLM20e7d, RTLM20e7e, RTLM20e7f\r\n      objectData = primitiveToObjectData(value as Primitive, client);\r\n    }\r\n\r\n    const mapSetMsg = ObjectMessage.fromValues(\r\n      {\r\n        operation: {\r\n          action: ObjectOperationAction.MAP_SET, // RTLM20e2\r\n          objectId, // RTLM20e3\r\n          mapSet: {\r\n            key, // RTLM20e6\r\n            value: objectData, // RTLM20e7\r\n          },\r\n        } as ObjectOperation<ObjectData>,\r\n      },\r\n      client.Utils,\r\n      client.MessageEncoding,\r\n    );\r\n\r\n    return [...createValueTypesMessages, mapSetMsg];\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static createMapRemoveMessage(realtimeObject: RealtimeObject, objectId: string, key: string): ObjectMessage {\r\n    const client = realtimeObject.getClient();\r\n\r\n    if (typeof key !== 'string') {\r\n      throw new client.ErrorInfo('Map key should be string', 40003, 400);\r\n    }\r\n\r\n    const msg = ObjectMessage.fromValues(\r\n      {\r\n        operation: {\r\n          action: ObjectOperationAction.MAP_REMOVE, // RTLM21e2\r\n          objectId, // RTLM21e3\r\n          mapRemove: { key }, // RTLM21e5\r\n        } as ObjectOperation<ObjectData>,\r\n      },\r\n      client.Utils,\r\n      client.MessageEncoding,\r\n    );\r\n\r\n    return msg;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static validateKeyValue(realtimeObject: RealtimeObject, key: string, value: Value): void {\r\n    const client = realtimeObject.getClient();\r\n\r\n    if (typeof key !== 'string') {\r\n      throw new client.ErrorInfo('Map key should be string', 40003, 400);\r\n    }\r\n\r\n    if (\r\n      value === null ||\r\n      (typeof value !== 'string' &&\r\n        typeof value !== 'number' &&\r\n        typeof value !== 'boolean' &&\r\n        typeof value !== 'object')\r\n    ) {\r\n      throw new client.ErrorInfo('Map value data type is unsupported', 40013, 400); // OD4a\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns the value associated with the specified key in the underlying Map object.\r\n   *\r\n   * - If this map object is tombstoned (deleted), `undefined` is returned.\r\n   * - If no entry is associated with the specified key, `undefined` is returned.\r\n   * - If map entry is tombstoned (deleted), `undefined` is returned.\r\n   * - If the value associated with the provided key is an objectId string of another LiveObject, a reference to that LiveObject\r\n   * is returned, provided it exists in the local pool and is not tombstoned. Otherwise, `undefined` is returned.\r\n   * - If the value is not an objectId, then that value is returned.\r\n   *\r\n   * @spec RTLM5, RTLM5a\r\n   */\r\n  // force the key to be of type string as we only allow strings as key in a map\r\n  get<TKey extends keyof T & string>(key: TKey): T[TKey] | undefined {\r\n    if (this.isTombstoned()) {\r\n      return undefined;\r\n    }\r\n\r\n    const element = this._dataRef.data.get(key);\r\n\r\n    // RTLM5d1\r\n    if (element === undefined) {\r\n      return undefined;\r\n    }\r\n\r\n    // RTLM5d2a\r\n    if (element.tombstone === true) {\r\n      return undefined;\r\n    }\r\n\r\n    // data always exists for non-tombstoned elements\r\n    return this._getResolvedValueFromObjectData(element.data!) as T[TKey];\r\n  }\r\n\r\n  size(): number {\r\n    let size = 0;\r\n    for (const value of this._dataRef.data.values()) {\r\n      if (this._isMapEntryTombstoned(value)) {\r\n        // should not count tombstoned entries\r\n        continue;\r\n      }\r\n\r\n      size++;\r\n    }\r\n\r\n    return size;\r\n  }\r\n\r\n  *entries<TKey extends keyof T & string>(): IterableIterator<[TKey, T[TKey]]> {\r\n    for (const [key, entry] of this._dataRef.data.entries()) {\r\n      if (this._isMapEntryTombstoned(entry)) {\r\n        // do not return tombstoned entries\r\n        continue;\r\n      }\r\n\r\n      // data always exists for non-tombstoned elements\r\n      const value = this._getResolvedValueFromObjectData(entry.data!) as T[TKey];\r\n      yield [key as TKey, value];\r\n    }\r\n  }\r\n\r\n  *keys<TKey extends keyof T & string>(): IterableIterator<TKey> {\r\n    for (const [key] of this.entries<TKey>()) {\r\n      yield key;\r\n    }\r\n  }\r\n\r\n  *values<TKey extends keyof T & string>(): IterableIterator<T[TKey]> {\r\n    for (const [_, value] of this.entries<TKey>()) {\r\n      yield value;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Send a MAP_SET operation to the realtime system to set a key on this LiveMap object to a specified value.\r\n   *\r\n   * The change will be applied locally when the ACK is received from Realtime.\r\n   *\r\n   * @returns A promise which resolves upon receiving the ACK message for the published operation message\r\n   * and applying the operation locally.\r\n   * @spec RTLM20\r\n   */\r\n  async set<TKey extends keyof T & string>(\r\n    key: TKey,\r\n    value: T[TKey] | LiveCounterValueType | LiveMapValueType,\r\n  ): Promise<void> {\r\n    const msgs = await LiveMap.createMapSetMessage(this._realtimeObject, this.getObjectId(), key, value);\r\n    return this._realtimeObject.publishAndApply(msgs);\r\n  }\r\n\r\n  /**\r\n   * Send a MAP_REMOVE operation to the realtime system to tombstone a key on this LiveMap object.\r\n   *\r\n   * The change will be applied locally when the ACK is received from Realtime.\r\n   *\r\n   * @returns A promise which resolves upon receiving the ACK message for the published operation message\r\n   * and applying the operation locally.\r\n   * @spec RTLM21\r\n   */\r\n  async remove<TKey extends keyof T & string>(key: TKey): Promise<void> {\r\n    const msg = LiveMap.createMapRemoveMessage(this._realtimeObject, this.getObjectId(), key);\r\n    return this._realtimeObject.publishAndApply([msg]);\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTLM15\r\n   */\r\n  applyOperation(op: ObjectOperation<ObjectData>, msg: ObjectMessage, source: ObjectsOperationSource): boolean {\r\n    if (op.objectId !== this.getObjectId()) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot apply object operation with objectId=${op.objectId}, to this LiveMap with objectId=${this.getObjectId()}`,\r\n        92000,\r\n        400,\r\n      );\r\n    }\r\n\r\n    const opSerial = msg.serial!;\r\n    const opSiteCode = msg.siteCode!;\r\n    if (!this._canApplyOperation(opSerial, opSiteCode)) {\r\n      // _canApplyOperation already logs a warning for malformed serial values; only log\r\n      // the newness-check skip when the serials are well-formed\r\n      if (opSerial && opSiteCode) {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MICRO,\r\n          'LiveMap.applyOperation()',\r\n          `skipping ${op.action} op: op serial ${opSerial} <= site serial ${this._siteTimeserials[opSiteCode]}; objectId=${this.getObjectId()}`,\r\n        );\r\n      }\r\n      return false; // RTLM15b\r\n    }\r\n\r\n    // RTLM15c\r\n    if (source === ObjectsOperationSource.channel) {\r\n      // should update stored site serial immediately. doesn't matter if we successfully apply the op,\r\n      // as it's important to mark that the op was processed by the object\r\n      this._siteTimeserials[opSiteCode] = opSerial;\r\n    }\r\n\r\n    if (this.isTombstoned()) {\r\n      // this object is tombstoned so the operation cannot be applied\r\n      return false; // RTLM15e\r\n    }\r\n\r\n    let update: LiveMapUpdate<T> | LiveObjectUpdateNoop;\r\n    switch (op.action) {\r\n      case ObjectOperationAction.MAP_CREATE:\r\n        // RTLM15d1\r\n        update = this._applyMapCreate(op, msg);\r\n        break;\r\n\r\n      case ObjectOperationAction.MAP_SET:\r\n        if (this._client.Utils.isNil(op.mapSet)) {\r\n          this._logNoPayloadWarning(op);\r\n          return false;\r\n        }\r\n        // RTLM15d6\r\n        update = this._applyMapSet(op.mapSet, opSerial, msg);\r\n        break;\r\n\r\n      case ObjectOperationAction.MAP_REMOVE:\r\n        if (this._client.Utils.isNil(op.mapRemove)) {\r\n          this._logNoPayloadWarning(op);\r\n          return false;\r\n        }\r\n        // RTLM15d7\r\n        update = this._applyMapRemove(op.mapRemove, opSerial, msg.serialTimestamp, msg);\r\n        break;\r\n\r\n      case ObjectOperationAction.OBJECT_DELETE:\r\n        // RTLM15d5\r\n        update = this._applyObjectDelete(msg);\r\n        break;\r\n\r\n      case ObjectOperationAction.MAP_CLEAR:\r\n        // RTLM15d8\r\n        update = this._applyMapClear(msg);\r\n        break;\r\n\r\n      default:\r\n        // RTLM15d4 - log a warning and discard the message without taking any further action\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MAJOR,\r\n          'LiveMap.applyOperation()',\r\n          `object operation message received with unsupported action, skipping message; action=${op.action}, objectId=${this.getObjectId()}`,\r\n        );\r\n        return false;\r\n    }\r\n\r\n    this.notifyUpdated(update); // RTLM15d1a, RTLM15d6a, RTLM15d7a, RTLM15d5a, RTLM15d8a\r\n    return true; // RTLM15d1b, RTLM15d6b, RTLM15d7b, RTLM15d5b, RTLM15d8b\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTLM6\r\n   */\r\n  overrideWithObjectState(objectMessage: ObjectMessage): LiveMapUpdate<T> | LiveObjectUpdateNoop {\r\n    const objectState = objectMessage.object;\r\n    if (objectState == null) {\r\n      throw new this._client.ErrorInfo(`Missing object state; LiveMap objectId=${this.getObjectId()}`, 92000, 400);\r\n    }\r\n\r\n    if (objectState.objectId !== this.getObjectId()) {\r\n      throw new this._client.ErrorInfo(\r\n        `Invalid object state: object state objectId=${objectState.objectId}; LiveMap objectId=${this.getObjectId()}`,\r\n        92000,\r\n        400,\r\n      );\r\n    }\r\n\r\n    if (objectState.map?.semantics !== this._semantics) {\r\n      throw new this._client.ErrorInfo(\r\n        `Invalid object state: object state map semantics=${objectState.map?.semantics}; LiveMap semantics=${this._semantics}`,\r\n        92000,\r\n        400,\r\n      );\r\n    }\r\n\r\n    if (!this._client.Utils.isNil(objectState.createOp)) {\r\n      // it is expected that create operation can be missing in the object state, so only validate it when it exists\r\n      if (objectState.createOp.objectId !== this.getObjectId()) {\r\n        throw new this._client.ErrorInfo(\r\n          `Invalid object state: object state createOp objectId=${objectState.createOp?.objectId}; LiveMap objectId=${this.getObjectId()}`,\r\n          92000,\r\n          400,\r\n        );\r\n      }\r\n\r\n      if (objectState.createOp.action !== ObjectOperationAction.MAP_CREATE) {\r\n        throw new this._client.ErrorInfo(\r\n          `Invalid object state: object state createOp action=${objectState.createOp?.action}; LiveMap objectId=${this.getObjectId()}`,\r\n          92000,\r\n          400,\r\n        );\r\n      }\r\n\r\n      if (objectState.createOp.mapCreate?.semantics !== this._semantics) {\r\n        throw new this._client.ErrorInfo(\r\n          `Invalid object state: object state createOp map semantics=${objectState.createOp.mapCreate?.semantics}; LiveMap semantics=${this._semantics}`,\r\n          92000,\r\n          400,\r\n        );\r\n      }\r\n    }\r\n\r\n    // object's site serials are still updated even if it is tombstoned, so always use the site serials received from the op.\r\n    // should default to empty map if site serials do not exist on the object state, so that any future operation may be applied to this object.\r\n    this._siteTimeserials = objectState.siteTimeserials ?? {}; // RTLM6a\r\n\r\n    if (this.isTombstoned()) {\r\n      // this object is tombstoned. this is a terminal state which can't be overridden. skip the rest of object state message processing\r\n      return { noop: true };\r\n    }\r\n\r\n    if (objectState.tombstone) {\r\n      // tombstone this object and ignore the data from the object state message\r\n      return this.tombstone(objectMessage);\r\n    }\r\n\r\n    // otherwise override data for this object with data from the object state\r\n    const previousDataRef = this._dataRef;\r\n    this._createOperationIsMerged = false; // RTLM6b\r\n    this._clearTimeserial = objectState.map?.clearTimeserial; // RTLM6i\r\n    this._dataRef = this._liveMapDataFromMapEntries(objectState.map?.entries ?? {}); // RTLM6c\r\n    // RTLM6d\r\n    if (!this._client.Utils.isNil(objectState.createOp)) {\r\n      this._mergeInitialDataFromCreateOperation(objectState.createOp, objectMessage);\r\n    }\r\n\r\n    // update will contain the diff between previous value and new value from object state\r\n    const update = this._updateFromDataDiff(previousDataRef, this._dataRef);\r\n    // RTLM22c - _updateFromDataDiff collapses an empty key-diff (no map key changed) to a noop.\r\n    // pass it straight through without stamping the object message, mirroring the terminal noop\r\n    // return above (RTLM6e).\r\n    if (this._isNoopUpdate(update)) {\r\n      return update;\r\n    }\r\n    update.objectMessage = objectMessage;\r\n\r\n    return update;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  onGCInterval(): void {\r\n    // should remove any tombstoned entries from the underlying map data that have exceeded the GC grace period\r\n\r\n    const keysToDelete: string[] = [];\r\n    for (const [key, value] of this._dataRef.data.entries()) {\r\n      if (value.tombstone === true && Date.now() - value.tombstonedAt! >= this._realtimeObject.gcGracePeriod) {\r\n        keysToDelete.push(key);\r\n      }\r\n    }\r\n\r\n    keysToDelete.forEach((x) => this._dataRef.data.delete(x));\r\n  }\r\n\r\n  /**\r\n   * Override clearData to handle parent reference cleanup when this LiveMap is tombstoned.\r\n   *\r\n   * @internal\r\n   */\r\n  clearData(): LiveMapUpdate<T> | LiveObjectUpdateNoop {\r\n    // Remove all parent references for objects this map was referencing\r\n    for (const [key, entry] of this._dataRef.data.entries()) {\r\n      if (entry.data && 'objectId' in entry.data) {\r\n        const referencedObject = this._realtimeObject.getPool().get(entry.data.objectId);\r\n        if (referencedObject) {\r\n          referencedObject.removeParentReference(this, key);\r\n        }\r\n      }\r\n    }\r\n\r\n    // RTLM4 - Reset clearTimeserial to null for zero-value LiveMap\r\n    this._clearTimeserial = undefined;\r\n\r\n    // Call the parent clearData method\r\n    return super.clearData();\r\n  }\r\n\r\n  /**\r\n   * Returns an in-memory JavaScript object representation of this LiveMap.\r\n   * LiveMap values are recursively compacted using their own compact methods.\r\n   * Compacted LiveMaps are memoized to handle cyclic references (returned as in-memory pointers).\r\n   *\r\n   * Use compactJson() for a JSON-serializable representation.\r\n   *\r\n   * @internal\r\n   */\r\n  compact(visitedObjects?: Map<string, Record<string, any>>): CompactedValue<PublicLiveMap<T>> {\r\n    const visited = visitedObjects ?? new Map<string, Record<string, any>>();\r\n    const result: Record<keyof T, any> = {} as Record<keyof T, any>;\r\n\r\n    // Memoize the compacted result to handle circular references\r\n    visited.set(this.getObjectId(), result);\r\n\r\n    // Use public entries() method to ensure we only include publicly exposed properties\r\n    for (const [key, value] of this.entries()) {\r\n      if (value instanceof LiveMap) {\r\n        if (visited.has(value.getObjectId())) {\r\n          // If the LiveMap has already been visited, just reference it to avoid infinite loops\r\n          result[key] = visited.get(value.getObjectId());\r\n        } else {\r\n          // Otherwise, compact it\r\n          result[key] = value.compact(visited);\r\n        }\r\n        continue;\r\n      }\r\n\r\n      if (value instanceof LiveCounter) {\r\n        result[key] = value.value();\r\n        continue;\r\n      }\r\n\r\n      // other values are returned as-is\r\n      result[key] = value;\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * Returns a JSON-serializable representation of this LiveMap.\r\n   * LiveMap values are recursively compacted using their own compactJson methods.\r\n   * Cyclic references are represented as `{ objectId: string }` instead of in-memory pointers.\r\n   * Buffers are converted to base64 strings.\r\n   *\r\n   * Use compact() for an in-memory representation.\r\n   *\r\n   * @internal\r\n   */\r\n  compactJson(visitedObjectIds?: Set<string>): CompactedJsonValue<PublicLiveMap<T>> {\r\n    const visited = visitedObjectIds ?? new Set<string>();\r\n    const result: Record<keyof T, any> = {} as Record<keyof T, any>;\r\n\r\n    // Mark this object ID as visited to handle circular references\r\n    visited.add(this.getObjectId());\r\n\r\n    // Use public entries() method to ensure we only include publicly exposed properties\r\n    for (const [key, value] of this.entries()) {\r\n      if (value instanceof LiveMap) {\r\n        if (visited.has(value.getObjectId())) {\r\n          // If the LiveMap has already been visited, return its objectId to avoid infinite loops\r\n          result[key] = { objectId: value.getObjectId() };\r\n        } else {\r\n          // Otherwise, compact it\r\n          result[key] = value.compactJson(visited);\r\n        }\r\n        continue;\r\n      }\r\n\r\n      if (value instanceof LiveCounter) {\r\n        result[key] = value.value();\r\n        continue;\r\n      }\r\n\r\n      // Convert buffers to base64 strings\r\n      if (this._client.Platform.BufferUtils.isBuffer(value)) {\r\n        result[key] = this._client.Platform.BufferUtils.base64Encode(value);\r\n        continue;\r\n      }\r\n\r\n      // Other values return as is\r\n      result[key] = value;\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  /** @spec RTLM4 */\r\n  protected _getZeroValueData(): LiveMapData {\r\n    return { data: new Map<string, LiveMapEntry>() };\r\n  }\r\n\r\n  protected _updateFromDataDiff(\r\n    prevDataRef: LiveMapData,\r\n    newDataRef: LiveMapData,\r\n  ): LiveMapUpdate<T> | LiveObjectUpdateNoop {\r\n    const update: LiveMapUpdate<T> = { update: {}, _type: 'LiveMapUpdate' };\r\n\r\n    for (const [key, currentEntry] of prevDataRef.data.entries()) {\r\n      const typedKey: keyof T & string = key;\r\n      // any non-tombstoned properties that exist on a current map, but not in the new data - got removed\r\n      if (currentEntry.tombstone === false && !newDataRef.data.has(typedKey)) {\r\n        update.update[typedKey] = 'removed';\r\n      }\r\n    }\r\n\r\n    for (const [key, newEntry] of newDataRef.data.entries()) {\r\n      const typedKey: keyof T & string = key;\r\n      if (!prevDataRef.data.has(typedKey)) {\r\n        // if property does not exist in the current map, but new data has it as a non-tombstoned property - got updated\r\n        if (newEntry.tombstone === false) {\r\n          update.update[typedKey] = 'updated';\r\n          continue;\r\n        }\r\n\r\n        // otherwise, if new data has this prop tombstoned - do nothing, as property didn't exist anyway\r\n        if (newEntry.tombstone === true) {\r\n          continue;\r\n        }\r\n      }\r\n\r\n      // properties that exist both in current and new map data need to have their values compared to decide on the update type\r\n      const currentEntry = prevDataRef.data.get(typedKey)!;\r\n\r\n      // compare tombstones first\r\n      if (currentEntry.tombstone === true && newEntry.tombstone === false) {\r\n        // current prop is tombstoned, but new is not. it means prop was updated to a meaningful value\r\n        update.update[typedKey] = 'updated';\r\n        continue;\r\n      }\r\n      if (currentEntry.tombstone === false && newEntry.tombstone === true) {\r\n        // current prop is not tombstoned, but new is. it means prop was removed\r\n        update.update[typedKey] = 'removed';\r\n        continue;\r\n      }\r\n      if (currentEntry.tombstone === true && newEntry.tombstone === true) {\r\n        // both props are tombstoned - treat as noop, as there is no data to compare.\r\n        continue;\r\n      }\r\n\r\n      // both props exist and are not tombstoned, need to compare values with deep equals to see if it was changed\r\n      const valueChanged = !dequal(currentEntry.data, newEntry.data);\r\n      if (valueChanged) {\r\n        update.update[typedKey] = 'updated';\r\n        continue;\r\n      }\r\n    }\r\n\r\n    // RTLM22c - as an exception to RTLM22b: if the computed update contains no changed keys (it is\r\n    // empty) no map key actually changed, so instead of returning an update return a LiveMapUpdate\r\n    // object with noop set to true (RTLO4b4b), as in RTLM16b. This exception must not be applied when\r\n    // the diff is computed for a tombstone per RTLO4e5; LiveObject.tombstone re-synthesizes a\r\n    // non-noop update via _createNoChangeUpdate() so the RTLO4b4c3c listener teardown still fires.\r\n    if (Object.keys(update.update).length === 0) {\r\n      return { noop: true };\r\n    }\r\n\r\n    return update;\r\n  }\r\n\r\n  protected _createNoChangeUpdate(): LiveMapUpdate<T> {\r\n    // RTLO4e5 tombstone carve-out (RTLM22c) - an empty no-change update for a map with no\r\n    // non-tombstoned entries\r\n    return { update: {}, _type: 'LiveMapUpdate' };\r\n  }\r\n\r\n  protected _mergeInitialDataFromCreateOperation(\r\n    objectOperation: ObjectOperation<ObjectData>,\r\n    msg: ObjectMessage,\r\n  ): LiveMapUpdate<T> {\r\n    // RTLM23 - resolve mapCreate from either the direct property or the one from which mapCreateWithObjectId was derived\r\n    const mapCreate = objectOperation.mapCreate ?? objectOperation.mapCreateWithObjectId?._derivedFrom;\r\n\r\n    if (this._client.Utils.isNil(mapCreate)) {\r\n      // if a map object is missing for the MAP_CREATE op, the initial value is implicitly an empty map.\r\n      // in this case there is nothing to merge into the current map, so we can just end processing the op.\r\n      return { update: {}, objectMessage: msg, _type: 'LiveMapUpdate' };\r\n    }\r\n\r\n    const aggregatedUpdate: LiveMapUpdate<T> = {\r\n      update: {},\r\n      objectMessage: msg,\r\n      _type: 'LiveMapUpdate',\r\n    };\r\n    // RTLM23a\r\n    // in order to apply MAP_CREATE op for an existing map, we should merge their underlying entries keys.\r\n    // we can do this by iterating over entries from MAP_CREATE op and apply changes on per-key basis as if we had MAP_SET, MAP_REMOVE operations.\r\n    Object.entries(mapCreate.entries ?? {}).forEach(([key, entry]) => {\r\n      // for a MAP_CREATE operation we must use the serial value available on an entry, instead of a serial on a message\r\n      const opSerial = entry.timeserial;\r\n      let update: LiveMapUpdate<T> | LiveObjectUpdateNoop;\r\n      if (entry.tombstone === true) {\r\n        // RTLM23a2 - entry in MAP_CREATE op is removed, try to apply MAP_REMOVE op\r\n        update = this._applyMapRemove({ key }, opSerial, entry.serialTimestamp, msg);\r\n      } else {\r\n        // RTLM23a1 - entry in MAP_CREATE op is not removed, try to set it via MAP_SET op\r\n        update = this._applyMapSet({ key, value: entry.data! }, opSerial, msg);\r\n      }\r\n\r\n      // skip noop updates\r\n      if ((update as LiveObjectUpdateNoop).noop) {\r\n        return;\r\n      }\r\n\r\n      // otherwise copy update data to aggregated update\r\n      Object.assign(aggregatedUpdate.update, update.update);\r\n    });\r\n\r\n    this._createOperationIsMerged = true; // RTLM23b\r\n\r\n    return aggregatedUpdate; // RTLM23c\r\n  }\r\n\r\n  private _logNoPayloadWarning(op: ObjectOperation<ObjectData>): void {\r\n    // a message with a missing operation payload is malformed; log a warning and discard\r\n    // it without aborting the processing of sibling operations in the same ProtocolMessage\r\n    this._client.Logger.logAction(\r\n      this._client.logger,\r\n      this._client.Logger.LOG_MAJOR,\r\n      'LiveMap.applyOperation()',\r\n      `no payload found for ${op.action} op, skipping message; objectId=${this.getObjectId()}`,\r\n    );\r\n  }\r\n\r\n  private _applyMapCreate(\r\n    op: ObjectOperation<ObjectData>,\r\n    msg: ObjectMessage,\r\n  ): LiveMapUpdate<T> | LiveObjectUpdateNoop {\r\n    if (this._createOperationIsMerged) {\r\n      // There can't be two different create operation for the same object id, because the object id\r\n      // fully encodes that operation. This means we can safely ignore any new incoming create operations\r\n      // if we already merged it once.\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'LiveMap._applyMapCreate()',\r\n        `skipping applying MAP_CREATE op on a map instance as it was already applied before; objectId=${this.getObjectId()}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    // RTLM23 - resolve mapCreate from either the direct property or the one from which mapCreateWithObjectId was derived\r\n    const mapCreate = op.mapCreate ?? op.mapCreateWithObjectId?._derivedFrom;\r\n\r\n    if (this._semantics !== mapCreate?.semantics) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot apply MAP_CREATE op on LiveMap objectId=${this.getObjectId()}; map's semantics=${this._semantics}, but op expected ${mapCreate?.semantics}`,\r\n        92000,\r\n        400,\r\n      );\r\n    }\r\n\r\n    return this._mergeInitialDataFromCreateOperation(op, msg);\r\n  }\r\n\r\n  /** @spec RTLM7, RTLM7d3 */\r\n  private _applyMapSet(\r\n    op: MapSet<ObjectData>,\r\n    opSerial: string | undefined,\r\n    msg: ObjectMessage,\r\n  ): LiveMapUpdate<T> | LiveObjectUpdateNoop {\r\n    const { ErrorInfo, Utils } = this._client;\r\n\r\n    // RTLM7h - Check operation's serial against clearTimeserial first\r\n    if (this._clearTimeserial && (!opSerial || this._clearTimeserial >= opSerial)) {\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'LiveMap._applyMapSet()',\r\n        `skipping update for key=\"${op.key}\": op serial ${opSerial} <= clear serial ${this._clearTimeserial}; objectId=${this.getObjectId()}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    const existingEntry = this._dataRef.data.get(op.key);\r\n    // RTLM7a\r\n    if (existingEntry && !this._canApplyMapEntryOperation(existingEntry.timeserial, opSerial)) {\r\n      // RTLM7a1 - the operation's serial <= the entry's serial, ignore the operation.\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'LiveMap._applyMapSet()',\r\n        `skipping update for key=\"${op.key}\": op serial ${opSerial?.toString()} <= entry serial ${existingEntry.timeserial?.toString()}; objectId=${this.getObjectId()}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    if (Utils.isNil(op.value) || (Utils.isNil(op.value.objectId) && Utils.isNil(getObjectDataPrimitive(op.value)))) {\r\n      throw new ErrorInfo(\r\n        `Invalid object data for MAP_SET op on objectId=${this.getObjectId()} on key=\"${op.key}\"`,\r\n        92000,\r\n        400,\r\n      );\r\n    }\r\n\r\n    let liveData: LiveMapObjectData;\r\n    // RTLM7g\r\n    if (!Utils.isNil(op.value.objectId)) {\r\n      liveData = { objectId: op.value.objectId } as ObjectIdObjectData;\r\n      // this MAP_SET op is setting a key to point to another object via its object id,\r\n      // but it is possible that we don't have the corresponding object in the pool yet (for example, we haven't seen the *_CREATE op for it).\r\n      // we don't want to return undefined from this map's .get() method even if we don't have the object,\r\n      // so instead we create a zero-value object for that object id if it not exists.\r\n      this._realtimeObject.getPool().createZeroValueObjectIfNotExists(op.value.objectId); // RTLM7g1\r\n    } else {\r\n      liveData = op.value;\r\n    }\r\n\r\n    if (existingEntry) {\r\n      // If there was an existing entry, we need to handle parent reference changes\r\n      if (existingEntry.data && 'objectId' in existingEntry.data) {\r\n        // Remove parent reference from the old object\r\n        const oldReferencedObject = this._realtimeObject.getPool().get(existingEntry.data.objectId);\r\n        if (oldReferencedObject) {\r\n          oldReferencedObject.removeParentReference(this, op.key);\r\n        }\r\n      }\r\n\r\n      // RTLM7a2\r\n      existingEntry.tombstone = false; // RTLM7a2c\r\n      existingEntry.tombstonedAt = undefined; // RTLM7a2d\r\n      existingEntry.timeserial = opSerial; // RTLM7a2b\r\n      existingEntry.data = liveData; // RTLM7a2e\r\n    } else {\r\n      // RTLM7b, RTLM7b4\r\n      const newEntry: LiveMapEntry = {\r\n        tombstone: false, // RTLM7b2\r\n        tombstonedAt: undefined, // RTLM7b3\r\n        timeserial: opSerial,\r\n        data: liveData,\r\n      };\r\n      this._dataRef.data.set(op.key, newEntry);\r\n    }\r\n\r\n    // Add parent reference to the new object (if it's an object reference)\r\n    if ('objectId' in liveData) {\r\n      const newReferencedObject = this._realtimeObject.getPool().get(liveData.objectId);\r\n      if (newReferencedObject) {\r\n        newReferencedObject.addParentReference(this, op.key);\r\n      }\r\n    }\r\n\r\n    const update: LiveMapUpdate<T> = {\r\n      update: {},\r\n      objectMessage: msg,\r\n      _type: 'LiveMapUpdate',\r\n    };\r\n    const typedKey: keyof T & string = op.key;\r\n    update.update[typedKey] = 'updated';\r\n\r\n    return update;\r\n  }\r\n\r\n  /** @spec RTLM8, RTLM8c4 */\r\n  private _applyMapRemove(\r\n    op: MapRemove,\r\n    opSerial: string | undefined,\r\n    opTimestamp: number | undefined,\r\n    msg: ObjectMessage,\r\n  ): LiveMapUpdate<T> | LiveObjectUpdateNoop {\r\n    // RTLM8g - Check operation's serial against clearTimeserial first\r\n    if (this._clearTimeserial && (!opSerial || this._clearTimeserial >= opSerial)) {\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'LiveMap._applyMapRemove()',\r\n        `skipping remove for key=\"${op.key}\": op serial ${opSerial} <= clear serial ${this._clearTimeserial}; objectId=${this.getObjectId()}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    const existingEntry = this._dataRef.data.get(op.key);\r\n    // RTLM8a\r\n    if (existingEntry && !this._canApplyMapEntryOperation(existingEntry.timeserial, opSerial)) {\r\n      // RTLM8a1 - the operation's serial <= the entry's serial, ignore the operation.\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'LiveMap._applyMapRemove()',\r\n        `skipping remove for key=\"${op.key}\": op serial ${opSerial?.toString()} <= entry serial ${existingEntry.timeserial?.toString()}; objectId=${this.getObjectId()}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    if (existingEntry) {\r\n      // Handle parent reference removal for object references\r\n      if (existingEntry.data && 'objectId' in existingEntry.data) {\r\n        // Remove parent reference from the object that was being referenced\r\n        const referencedObject = this._realtimeObject.getPool().get(existingEntry.data.objectId);\r\n        if (referencedObject) {\r\n          referencedObject.removeParentReference(this, op.key);\r\n        }\r\n      }\r\n\r\n      // RTLM8a2\r\n      existingEntry.tombstone = true; // RTLM8a2c\r\n      existingEntry.tombstonedAt = this._calculateTombstonedAt(\r\n        opTimestamp,\r\n        'LiveMap._applyMapRemove()',\r\n        `key=\"${op.key}\", objectId=${this.getObjectId()}`,\r\n      ); // RTLM8a2d\r\n      existingEntry.timeserial = opSerial; // RTLM8a2b\r\n      existingEntry.data = undefined; // RTLM8a2a\r\n    } else {\r\n      // RTLM8b, RTLM8b1\r\n      const newEntry: LiveMapEntry = {\r\n        tombstone: true, // RTLM8b2\r\n        tombstonedAt: this._calculateTombstonedAt(\r\n          opTimestamp,\r\n          'LiveMap._applyMapRemove()',\r\n          `key=\"${op.key}\", objectId=${this.getObjectId()}`,\r\n        ), // RTLM8b3\r\n        timeserial: opSerial,\r\n        data: undefined,\r\n      };\r\n      this._dataRef.data.set(op.key, newEntry);\r\n    }\r\n\r\n    const update: LiveMapUpdate<T> = {\r\n      update: {},\r\n      objectMessage: msg,\r\n      _type: 'LiveMapUpdate',\r\n    };\r\n    const typedKey: keyof T & string = op.key;\r\n    update.update[typedKey] = 'removed';\r\n\r\n    return update;\r\n  }\r\n\r\n  /** @spec RTLM24 */\r\n  private _applyMapClear(objectMessage: ObjectMessage): LiveMapUpdate<T> | LiveObjectUpdateNoop {\r\n    const opSerial = objectMessage.serial!;\r\n\r\n    if (this._clearTimeserial != null && this._clearTimeserial > opSerial) {\r\n      // RTLM24c\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'LiveMap._applyMapClear()',\r\n        `skipping MAP_CLEAR: op serial ${opSerial} < current clear serial ${this._clearTimeserial}; objectId=${this.getObjectId()}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    // RTLM24d\r\n    this._client.Logger.logAction(\r\n      this._client.logger,\r\n      this._client.Logger.LOG_MICRO,\r\n      'LiveMap._applyMapClear()',\r\n      `updating clearTimeserial; previous=${this._clearTimeserial}, new=${opSerial}; objectId=${this.getObjectId()}`,\r\n    );\r\n    this._clearTimeserial = opSerial;\r\n\r\n    const update: LiveMapUpdate<T> = {\r\n      update: {},\r\n      objectMessage,\r\n      _type: 'LiveMapUpdate',\r\n    };\r\n\r\n    // RTLM24e\r\n    for (const [key, entry] of this._dataRef.data.entries()) {\r\n      const entrySerial = entry.timeserial;\r\n      // RTLM24e1\r\n      if (entrySerial == null || this._clearTimeserial > entrySerial) {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MICRO,\r\n          'LiveMap._applyMapClear()',\r\n          `clearing entry; key=\"${key}\", entry serial=${entrySerial}, clear serial=${this._clearTimeserial}, objectId=${this.getObjectId()}`,\r\n        );\r\n\r\n        // Handle parent reference removal for object references\r\n        if (entry.data && 'objectId' in entry.data) {\r\n          // Remove parent reference from the object that was being referenced\r\n          const referencedObject = this._realtimeObject.getPool().get(entry.data.objectId);\r\n          if (referencedObject) {\r\n            referencedObject.removeParentReference(this, key);\r\n          }\r\n        }\r\n\r\n        // RTLM24e1a - Remove the entry from the internal data map entirely\r\n        this._dataRef.data.delete(key);\r\n\r\n        const typedKey: keyof T & string = key;\r\n        update.update[typedKey] = 'removed'; // RTLM24e1b\r\n      } else {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MICRO,\r\n          'LiveMap._applyMapClear()',\r\n          `skipping clearing entry; key=\"${key}\", entry serial=${entrySerial}, clear serial=${this._clearTimeserial}, objectId=${this.getObjectId()}`,\r\n        );\r\n      }\r\n    }\r\n\r\n    return update; // RTLM24f\r\n  }\r\n\r\n  /**\r\n   * Returns true if the serials of the given operation and entry indicate that\r\n   * the operation should be applied to the entry, following the CRDT semantics of this LiveMap.\r\n   * @spec RTLM9\r\n   */\r\n  private _canApplyMapEntryOperation(mapEntrySerial: string | undefined, opSerial: string | undefined): boolean {\r\n    // for LWW CRDT semantics (the only supported LiveMap semantic) an operation\r\n    // should only be applied if its serial is strictly greater (\"after\") than an entry's serial.\r\n\r\n    if (!mapEntrySerial && !opSerial) {\r\n      // RTLM9b - if both serials are nullish or empty strings, we treat them as the \"earliest possible\" serials,\r\n      // in which case they are \"equal\", so the operation should not be applied\r\n      return false;\r\n    }\r\n\r\n    if (!mapEntrySerial) {\r\n      // RTLM9d - any operation serial is greater than non-existing entry serial\r\n      return true;\r\n    }\r\n\r\n    if (!opSerial) {\r\n      // RTLM9c - non-existing operation serial is lower than any entry serial\r\n      return false;\r\n    }\r\n\r\n    // RTLM9e - if both serials exist, compare them lexicographically\r\n    return opSerial > mapEntrySerial;\r\n  }\r\n\r\n  private _liveMapDataFromMapEntries(entries: Record<string, ObjectsMapEntry<ObjectData>>): LiveMapData {\r\n    const liveMapData: LiveMapData = {\r\n      data: new Map<string, LiveMapEntry>(),\r\n    };\r\n\r\n    // need to iterate over entries to correctly process optional parameters\r\n    Object.entries(entries ?? {}).forEach(([key, entry]) => {\r\n      let liveData: LiveMapObjectData | undefined = undefined;\r\n\r\n      if (!this._client.Utils.isNil(entry.data)) {\r\n        if (!this._client.Utils.isNil(entry.data.objectId)) {\r\n          liveData = { objectId: entry.data.objectId } as ObjectIdObjectData;\r\n        } else {\r\n          liveData = entry.data;\r\n        }\r\n      }\r\n\r\n      const liveDataEntry: LiveMapEntry = {\r\n        timeserial: entry.timeserial,\r\n        data: liveData,\r\n        // consider object as tombstoned only if we received an explicit flag stating that. otherwise it exists\r\n        tombstone: entry.tombstone === true,\r\n        tombstonedAt:\r\n          entry.tombstone === true\r\n            ? this._calculateTombstonedAt(\r\n                entry.serialTimestamp,\r\n                'LiveMap._liveMapDataFromMapEntries()',\r\n                `key=\"${key}\", objectId=${this.getObjectId()}`,\r\n              )\r\n            : undefined, // RTLM6c1\r\n      };\r\n\r\n      liveMapData.data.set(key, liveDataEntry);\r\n    });\r\n\r\n    return liveMapData;\r\n  }\r\n\r\n  /**\r\n   * Returns value as is if object data stores a primitive type, or a reference to another LiveObject from the pool if it stores an objectId.\r\n   */\r\n  private _getResolvedValueFromObjectData(data: LiveMapObjectData): Value | undefined {\r\n    // if object data stores primitive value, just return it as is.\r\n    const primitiveValue = getObjectDataPrimitive(data);\r\n    if (primitiveValue != null) {\r\n      return primitiveValue; // RTLM5d2b, RTLM5d2c, RTLM5d2d, RTLM5d2e\r\n    }\r\n\r\n    // RTLM5d2f - if object data has an objectId reference, get the actual object from the pool\r\n    if ('objectId' in data) {\r\n      const refObject: LiveObject | undefined = this._realtimeObject.getPool().get(data.objectId);\r\n      if (!refObject) {\r\n        return undefined; // RTLM5d2f1\r\n      }\r\n\r\n      if (refObject.isTombstoned()) {\r\n        // tombstoned objects must not be surfaced to the end users\r\n        return undefined;\r\n      }\r\n\r\n      return refObject as unknown as PublicLiveObject; // RTLM5d2f2\r\n    }\r\n\r\n    return undefined; // RTLM5d2g\r\n  }\r\n\r\n  private _isMapEntryTombstoned(entry: LiveMapEntry): boolean {\r\n    if (entry.tombstone === true) {\r\n      return true;\r\n    }\r\n\r\n    // data always exists for non-tombstoned entries\r\n    const data = entry.data!;\r\n    if ('objectId' in data) {\r\n      const refObject = this._realtimeObject.getPool().get(data.objectId);\r\n\r\n      if (refObject?.isTombstoned()) {\r\n        // entry that points to tombstoned object should be considered tombstoned as well\r\n        return true;\r\n      }\r\n    }\r\n\r\n    return false;\r\n  }\r\n}\r\n", "export const ROOT_OBJECT_ID = 'root';\n", "import type BaseClient from 'common/lib/client/baseclient';\r\nimport type EventEmitter from 'common/lib/util/eventemitter';\r\nimport type { EventCallback, Subscription } from '../../../ably';\r\nimport { ROOT_OBJECT_ID } from './constants';\r\nimport { InstanceEvent } from './instance';\r\nimport { ObjectData, ObjectMessage, ObjectOperation } from './objectmessage';\r\nimport { Path } from './path';\r\nimport { PathEvent } from './pathobjectsubscriptionregister';\r\nimport { ObjectsOperationSource, RealtimeObject } from './realtimeobject';\r\nimport type { LiveMap } from './livemap';\r\n\r\nexport enum LiveObjectSubscriptionEvent {\r\n  updated = 'updated',\r\n}\r\n\r\nexport interface LiveObjectData {\r\n  data: any;\r\n}\r\n\r\nexport interface LiveObjectUpdate {\r\n  _type: 'LiveMapUpdate' | 'LiveCounterUpdate';\r\n  /** Delta of the change */\r\n  update: any;\r\n  /** Object message that caused an update to an object, if available */\r\n  objectMessage?: ObjectMessage;\r\n  /** Indicates whether this update is a result of a tombstone (delete) operation. */\r\n  tombstone?: boolean;\r\n}\r\n\r\nexport interface LiveObjectUpdateNoop {\r\n  // have optional update field with undefined type so it's not possible to create a noop object with a meaningful update property.\r\n  update?: undefined;\r\n  noop: true;\r\n}\r\n\r\nexport abstract class LiveObject<\r\n  TData extends LiveObjectData = LiveObjectData,\r\n  TUpdate extends LiveObjectUpdate = LiveObjectUpdate,\r\n> {\r\n  protected _client: BaseClient;\r\n  protected _subscriptions: EventEmitter;\r\n  protected _objectId: string;\r\n  /**\r\n   * Represents an aggregated value for an object, which combines the initial value for an object from the create operation,\r\n   * and all object operations applied to the object.\r\n   */\r\n  protected _dataRef: TData;\r\n  protected _siteTimeserials: Record<string, string>;\r\n  protected _createOperationIsMerged: boolean;\r\n  private _tombstone: boolean;\r\n  private _tombstonedAt: number | undefined;\r\n  /**\r\n   * Track parent references - which LiveMap objects contain this object and at which keys.\r\n   * Multiple parents can reference the same object, so we use a Map of parent to Set of keys for efficient lookups.\r\n   */\r\n  private _parentReferences: Map<LiveMap, Set<string>>;\r\n\r\n  protected constructor(\r\n    protected _realtimeObject: RealtimeObject,\r\n    objectId: string,\r\n  ) {\r\n    this._client = this._realtimeObject.getClient();\r\n    this._subscriptions = new this._client.EventEmitter(this._client.logger);\r\n    this._objectId = objectId;\r\n    this._dataRef = this._getZeroValueData();\r\n    // use empty map of serials by default, so any future operation can be applied to this object\r\n    this._siteTimeserials = {};\r\n    this._createOperationIsMerged = false;\r\n    this._tombstone = false;\r\n    this._parentReferences = new Map<LiveMap, Set<string>>();\r\n  }\r\n\r\n  subscribe(listener: EventCallback<InstanceEvent>): Subscription {\r\n    this._subscriptions.on(LiveObjectSubscriptionEvent.updated, listener);\r\n\r\n    const unsubscribe = () => {\r\n      this._subscriptions.off(LiveObjectSubscriptionEvent.updated, listener);\r\n    };\r\n\r\n    return { unsubscribe };\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  getObjectId(): string {\r\n    return this._objectId;\r\n  }\r\n\r\n  /**\r\n   * Emits the {@link LiveObjectSubscriptionEvent.updated} event with provided update object if it isn't a noop.\r\n   * Also notifies the path object subscriptions about path-based events.\r\n   *\r\n   * @internal\r\n   */\r\n  notifyUpdated(update: TUpdate | LiveObjectUpdateNoop): void {\r\n    if (this._isNoopUpdate(update)) {\r\n      // do not emit update events for noop updates\r\n      return;\r\n    }\r\n\r\n    this._notifyInstanceSubscriptions(update);\r\n    this._notifyPathSubscriptions(update);\r\n\r\n    if (update.tombstone) {\r\n      // deregister all listeners if update was a result of a tombstone operation\r\n      this._subscriptions.off();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Clears the object's data, cancels any buffered operations and sets the tombstone flag to `true`.\r\n   * The root object can never be tombstoned (RTLO4e10); such attempts return a noop update.\r\n   *\r\n   * @internal\r\n   */\r\n  tombstone(objectMessage: ObjectMessage): TUpdate | LiveObjectUpdateNoop {\r\n    // RTLO4e10 - the root object must always exist in the ObjectsPool (RTO3b); the realtime\r\n    // system never publishes an OBJECT_DELETE operation or a tombstoned object state for it,\r\n    // so an attempt to tombstone it indicates a faulty message. log a warning and skip it\r\n    if (this.getObjectId() === ROOT_OBJECT_ID) {\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MAJOR,\r\n        'LiveObject.tombstone()',\r\n        `attempt to tombstone the root object was rejected; serial=${objectMessage.serial}, siteCode=${objectMessage.siteCode}, message id: ${objectMessage.id}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    this._tombstone = true; // RTLO4e2\r\n    this._tombstonedAt = this._calculateTombstonedAt(\r\n      objectMessage.serialTimestamp,\r\n      'LiveObject.tombstone()',\r\n      `objectId=${this.getObjectId()}`,\r\n    ); // RTLO4e3\r\n    // RTLO4e5 - compute the diff between the pre-clear data and the zero value. Per the RTLC14c /\r\n    // RTLM22c tombstone carve-out, that noop exception \"must not be applied when the diff is\r\n    // computed for a tombstone\": tombstoning an already-empty object yields a noop diff, but the\r\n    // resulting tombstone update (RTLO4b4e) must still be delivered so it drives the RTLO4b4c3c\r\n    // listener teardown. So when the diff collapses to a noop, synthesize the typed no-change\r\n    // update instead, leaving a real (non-noop) update to stamp.\r\n    const diff = this.clearData(); // RTLO4e4\r\n    const update: TUpdate = this._isNoopUpdate(diff) ? this._createNoChangeUpdate() : diff;\r\n    update.objectMessage = objectMessage; // RTLO4e7\r\n    update.tombstone = true; // RTLO4e6\r\n\r\n    return update; // RTLO4e8\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  isTombstoned(): boolean {\r\n    return this._tombstone;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  tombstonedAt(): number | undefined {\r\n    return this._tombstonedAt;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  clearData(): TUpdate | LiveObjectUpdateNoop {\r\n    const previousDataRef = this._dataRef;\r\n    this._dataRef = this._getZeroValueData();\r\n    return this._updateFromDataDiff(previousDataRef, this._dataRef);\r\n  }\r\n\r\n  /**\r\n   * Add a parent reference indicating that this object is referenced by the given parent LiveMap at the specified key.\r\n   *\r\n   * @internal\r\n   */\r\n  addParentReference(parent: LiveMap, key: string): void {\r\n    const keys = this._parentReferences.get(parent);\r\n\r\n    if (keys) {\r\n      keys.add(key);\r\n    } else {\r\n      this._parentReferences.set(parent, new Set([key]));\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Remove a parent reference indicating that this object is no longer referenced by the given parent LiveMap at the specified key.\r\n   *\r\n   * @internal\r\n   */\r\n  removeParentReference(parent: LiveMap, key: string): void {\r\n    const keys = this._parentReferences.get(parent);\r\n\r\n    if (keys) {\r\n      keys.delete(key);\r\n      // If no more keys for this parent, remove the parent entry entirely\r\n      if (keys.size === 0) {\r\n        this._parentReferences.delete(parent);\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Clears all parent references for this object.\r\n   *\r\n   * @internal\r\n   */\r\n  clearParentReferences(): void {\r\n    this._parentReferences.clear();\r\n  }\r\n\r\n  /**\r\n   * Calculates and returns all possible paths to this object from the root object by traversing up the parent hierarchy.\r\n   * Uses iterative DFS with an explicit stack. Each path is represented as an array of keys from root to this object.\r\n   *\r\n   * @internal\r\n   */\r\n  getFullPaths(): Path[] {\r\n    const paths: Path[] = [];\r\n\r\n    const stack: { obj: LiveObject; currentPath: Path; visited: Set<LiveObject> }[] = [\r\n      { obj: this, currentPath: [], visited: new Set() },\r\n    ];\r\n\r\n    while (stack.length > 0) {\r\n      const { obj, currentPath, visited } = stack.pop()!;\r\n\r\n      // Check for cyclic references\r\n      if (visited.has(obj)) {\r\n        continue; // Skip this path to prevent infinite loops\r\n      }\r\n\r\n      // Create new visited set for this path\r\n      const newVisited = new Set(visited);\r\n      newVisited.add(obj);\r\n\r\n      if (obj.getObjectId() === ROOT_OBJECT_ID) {\r\n        // Reached the root object, add the current path\r\n        paths.push(currentPath);\r\n        continue;\r\n      }\r\n\r\n      // Otherwise, add work items for each parent-key combination to the stack\r\n      for (const [parent, keys] of obj._parentReferences) {\r\n        for (const key of keys) {\r\n          stack.push({\r\n            obj: parent,\r\n            currentPath: [key, ...currentPath],\r\n            visited: newVisited,\r\n          });\r\n        }\r\n      }\r\n    }\r\n\r\n    return paths;\r\n  }\r\n\r\n  /**\r\n   * Returns true if the given serial indicates that the operation to which it belongs should be applied to the object.\r\n   *\r\n   * An operation should be applied if its serial is strictly greater than the serial in the `siteTimeserials` map for the same site.\r\n   * If `siteTimeserials` map does not contain a serial for the same site, the operation should be applied.\r\n   */\r\n  protected _canApplyOperation(opSerial: string | undefined, opSiteCode: string | undefined): boolean {\r\n    // RTLO4a3 - an operation with invalid serial values is not applied; log a warning and\r\n    // skip it instead of throwing, so one malformed operation cannot abort the processing\r\n    // of sibling operations in the same ProtocolMessage.\r\n    if (!opSerial || !opSiteCode) {\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MAJOR,\r\n        'LiveObject._canApplyOperation()',\r\n        `object operation message has invalid serial values, skipping operation; serial=${opSerial}, siteCode=${opSiteCode}, objectId=${this.getObjectId()}`,\r\n      );\r\n      return false;\r\n    }\r\n\r\n    const siteSerial = this._siteTimeserials[opSiteCode];\r\n    return !siteSerial || opSerial > siteSerial;\r\n  }\r\n\r\n  protected _applyObjectDelete(objectMessage: ObjectMessage): TUpdate | LiveObjectUpdateNoop {\r\n    return this.tombstone(objectMessage);\r\n  }\r\n\r\n  /**\r\n   * Calculate a tombstonedAt timestamp from the provided serialTimestamp,\r\n   * falling back to the local clock if not available.\r\n   *\r\n   * @spec RTLO6\r\n   */\r\n  protected _calculateTombstonedAt(serialTimestamp: number | undefined, action: string, details?: string): number {\r\n    if (serialTimestamp != null) {\r\n      return serialTimestamp; // RTLO6a\r\n    }\r\n\r\n    // RTLO6b1\r\n    this._client.Logger.logAction(\r\n      this._client.logger,\r\n      this._client.Logger.LOG_MINOR,\r\n      action,\r\n      `no \"serialTimestamp\" found for an operation, using local clock instead; ${details}`,\r\n    );\r\n    return Date.now(); // RTLO6b\r\n  }\r\n\r\n  private _notifyInstanceSubscriptions(update: TUpdate): void {\r\n    const event: InstanceEvent = {\r\n      // Do not expose object sync messages as they do not represent a single operation on an object\r\n      message: update.objectMessage?.isOperationMessage() ? update.objectMessage : undefined,\r\n    };\r\n    this._subscriptions.emit(LiveObjectSubscriptionEvent.updated, event);\r\n  }\r\n\r\n  /**\r\n   * Notifies path-based subscriptions about changes to this object.\r\n   * For LiveMapUpdate events, each updated key also contributes a candidate\r\n   * path one segment deeper than this object's own path.\r\n   */\r\n  private _notifyPathSubscriptions(update: TUpdate): void {\r\n    const pathsToThis = this.getFullPaths();\r\n\r\n    if (pathsToThis.length === 0) {\r\n      // No paths to this object, skip notification\r\n      return;\r\n    }\r\n\r\n    // Do not expose object sync messages as they do not represent a single operation on an object\r\n    const operationObjectMessage = update.objectMessage?.isOperationMessage() ? update.objectMessage : undefined;\r\n\r\n    // Call notifyPathEvent() once for each path-to-this. Since\r\n    // notifyPathEvent() emits at most one event on each subscription, this\r\n    // means that we emit at most one event per path-to-this.\r\n    for (const pathToThis of pathsToThis) {\r\n      const preferenceOrderedCandidatePaths: Path[] = [pathToThis];\r\n\r\n      // For LiveMapUpdate, also add a candidate path per updated key. We insert these after\r\n      // pathToThis so that notifyPathEvent() picks pathToThis in the case where a given subscription\r\n      // covers multiple candidate paths (that is, we favour the shorter path).\r\n      if (update._type === 'LiveMapUpdate') {\r\n        const updatedKeys = Object.keys(update.update);\r\n\r\n        for (const key of updatedKeys) {\r\n          preferenceOrderedCandidatePaths.push([...pathToThis, key]);\r\n        }\r\n      }\r\n\r\n      const pathEvent: PathEvent = {\r\n        preferenceOrderedCandidatePaths,\r\n        message: operationObjectMessage,\r\n      };\r\n\r\n      this._realtimeObject.getPathObjectSubscriptionRegister().notifyPathEvent(pathEvent);\r\n    }\r\n  }\r\n\r\n  protected _isNoopUpdate(update: TUpdate | LiveObjectUpdateNoop): update is LiveObjectUpdateNoop {\r\n    return (update as LiveObjectUpdateNoop).noop === true;\r\n  }\r\n\r\n  /**\r\n   * Apply object operation message on this LiveObject.\r\n   *\r\n   * @returns `true` if the operation was applied successfully, `false` if it was skipped.\r\n   * @spec RTLC7g, RTLM15g\r\n   * @internal\r\n   */\r\n  abstract applyOperation(op: ObjectOperation<ObjectData>, msg: ObjectMessage, source: ObjectsOperationSource): boolean;\r\n  /**\r\n   * Overrides internal data for this LiveObject with object state from the given object message.\r\n   * Provided object state should hold a valid data for current LiveObject, e.g. counter data for LiveCounter, map data for LiveMap.\r\n   *\r\n   * Object states are received during sync sequence, and sync sequence is a source of truth for the current state of the objects,\r\n   * so we can use the data received from the sync sequence directly and override any data values or site serials this LiveObject has\r\n   * without the need to merge them.\r\n   *\r\n   * Returns an update object that describes the changes applied based on the object's previous value.\r\n   *\r\n   * @internal\r\n   */\r\n  abstract overrideWithObjectState(objectMessage: ObjectMessage): TUpdate | LiveObjectUpdateNoop;\r\n  /**\r\n   * @internal\r\n   */\r\n  abstract onGCInterval(): void;\r\n\r\n  protected abstract _getZeroValueData(): TData;\r\n  /**\r\n   * Calculate the update object based on the current LiveObject data and incoming new data.\r\n   *\r\n   * Returns a noop update when the data is unchanged (RTLC14c / RTLM22c).\r\n   */\r\n  protected abstract _updateFromDataDiff(prevDataRef: TData, newDataRef: TData): TUpdate | LiveObjectUpdateNoop;\r\n  /**\r\n   * Returns a typed update that represents \"no change\" (e.g. a counter delta of 0, or an empty\r\n   * map key-diff), used by {@link LiveObject.tombstone} to synthesize a deliverable tombstone\r\n   * update when the tombstone diff itself collapsed to a noop per the RTLC14c / RTLM22c carve-out.\r\n   */\r\n  protected abstract _createNoChangeUpdate(): TUpdate;\r\n  /**\r\n   * Merges the initial data from the create operation into the LiveObject.\r\n   *\r\n   * Client SDKs do not need to keep around the object operation that created the object,\r\n   * so we can merge the initial data the first time we receive it for the object,\r\n   * and work with aggregated value after that.\r\n   *\r\n   * This saves us from needing to merge the initial value with operations applied to\r\n   * the object every time the object is read.\r\n   */\r\n  protected abstract _mergeInitialDataFromCreateOperation(\r\n    objectOperation: ObjectOperation<ObjectData>,\r\n    msg: ObjectMessage,\r\n  ): TUpdate | LiveObjectUpdateNoop;\r\n}\r\n", "export const DEFAULTS = {\n  gcInterval: 1000 * 60 * 5, // 5 minutes\n  /**\n   * The SDK will attempt to use the `objectsGCGracePeriod` value provided by the server in the `connectionDetails` object of the `CONNECTED` event.\n   * If the server does not provide this value, the SDK will fall back to this default value.\n   *\n   * Must be > 2 minutes to ensure we keep tombstones long enough to avoid the possibility of receiving an operation\n   * with an earlier serial that would not have been applied if the tombstone still existed.\n   *\n   * Applies both for map entries tombstones and object tombstones.\n   */\n  gcGracePeriod: 1000 * 60 * 60 * 24, // 24 hours\n};\n", "import type BaseClient from 'common/lib/client/baseclient';\r\nimport { ROOT_OBJECT_ID } from './constants';\r\nimport { DEFAULTS } from './defaults';\r\nimport { LiveCounter } from './livecounter';\r\nimport { LiveMap } from './livemap';\r\nimport { LiveObject } from './liveobject';\r\nimport { ObjectId } from './objectid';\r\nimport { RealtimeObject } from './realtimeobject';\r\n\r\n/**\r\n * @internal\r\n * @spec RTO3\r\n */\r\nexport class ObjectsPool {\r\n  private _client: BaseClient;\r\n  private _pool: Map<string, LiveObject>; // RTO3a\r\n  private _gcInterval: ReturnType<typeof setInterval>;\r\n\r\n  constructor(private _realtimeObject: RealtimeObject) {\r\n    this._client = this._realtimeObject.getClient();\r\n    this._pool = this._createInitialPool();\r\n    this._gcInterval = setInterval(() => {\r\n      this._onGCInterval();\r\n    }, DEFAULTS.gcInterval);\r\n    // call nodejs's Timeout.unref to not require Node.js event loop to remain active due to this interval. see https://nodejs.org/api/timers.html#timeoutunref\r\n    this._gcInterval.unref?.();\r\n  }\r\n\r\n  get(objectId: string): LiveObject | undefined {\r\n    return this._pool.get(objectId);\r\n  }\r\n\r\n  getRoot(): LiveMap {\r\n    return this._pool.get(ROOT_OBJECT_ID) as LiveMap;\r\n  }\r\n\r\n  /**\r\n   * Returns all objects in the pool as an iterable.\r\n   * Used internally for operations that need to process all objects.\r\n   */\r\n  getAll(): IterableIterator<LiveObject> {\r\n    return this._pool.values();\r\n  }\r\n\r\n  /**\r\n   * Deletes objects from the pool for which object ids are not found in the provided array of ids.\r\n   *\r\n   * @spec RTO5c2 - remove objects whose ids were not received during the sync sequence\r\n   * @spec RTO5c2a - the root object must never be removed (RTO3b), even if absent from the sync\r\n   */\r\n  deleteExtraObjectIds(objectIds: string[]): void {\r\n    const poolObjectIds = [...this._pool.keys()];\r\n    const extraObjectIds = poolObjectIds.filter((x) => !objectIds.includes(x) && x !== ROOT_OBJECT_ID);\r\n\r\n    extraObjectIds.forEach((x) => this._pool.delete(x));\r\n  }\r\n\r\n  set(objectId: string, liveObject: LiveObject): void {\r\n    this._pool.set(objectId, liveObject);\r\n  }\r\n\r\n  /**\r\n   * Removes all objects but root from the pool and clears the data for root.\r\n   * Does not create a new root object, so the reference to the root object remains the same.\r\n   */\r\n  resetToInitialPool(emitUpdateEvents: boolean): void {\r\n    // clear the pool first and keep the root object\r\n    const root = this.getRoot();\r\n    this._pool.clear();\r\n    this._pool.set(root.getObjectId(), root);\r\n\r\n    // clear the data, this will only clear the root object\r\n    this.clearObjectsData(emitUpdateEvents);\r\n  }\r\n\r\n  /**\r\n   * Clears the data stored for all objects in the pool.\r\n   */\r\n  clearObjectsData(emitUpdateEvents: boolean): void {\r\n    for (const object of this._pool.values()) {\r\n      const update = object.clearData();\r\n      if (emitUpdateEvents) {\r\n        object.notifyUpdated(update);\r\n      }\r\n    }\r\n  }\r\n\r\n  /** @spec RTO6 */\r\n  createZeroValueObjectIfNotExists(objectId: string): LiveObject {\r\n    const existingObject = this.get(objectId);\r\n    if (existingObject) {\r\n      return existingObject; // RTO6a\r\n    }\r\n\r\n    const parsedObjectId = ObjectId.fromString(this._client, objectId); // RTO6b\r\n    let zeroValueObject: LiveObject;\r\n    switch (parsedObjectId.type) {\r\n      case 'map': {\r\n        zeroValueObject = LiveMap.zeroValue(this._realtimeObject, objectId); // RTO6b2\r\n        break;\r\n      }\r\n\r\n      case 'counter':\r\n        zeroValueObject = LiveCounter.zeroValue(this._realtimeObject, objectId); // RTO6b3\r\n        break;\r\n    }\r\n\r\n    this.set(objectId, zeroValueObject);\r\n    return zeroValueObject;\r\n  }\r\n\r\n  private _createInitialPool(): Map<string, LiveObject> {\r\n    const pool = new Map<string, LiveObject>();\r\n    // RTO3b\r\n    const root = LiveMap.zeroValue(this._realtimeObject, ROOT_OBJECT_ID);\r\n    pool.set(root.getObjectId(), root);\r\n    return pool;\r\n  }\r\n\r\n  private _onGCInterval(): void {\r\n    const toDelete: string[] = [];\r\n    for (const [objectId, obj] of this._pool.entries()) {\r\n      // tombstoned objects should be removed from the pool if they have been tombstoned for longer than grace period.\r\n      // by removing them from the local pool, LiveObjects plugin no longer keeps a reference to those objects, allowing JS's\r\n      // Garbage Collection to eventually free the memory for those objects, provided the user no longer references them either.\r\n      // RTO10c1b1 - the root object must never be removed from the pool (RTO3b). it can never\r\n      // become tombstoned per RTLO4e10, so this exclusion is an additional safeguard\r\n      if (\r\n        objectId !== ROOT_OBJECT_ID &&\r\n        obj.isTombstoned() &&\r\n        Date.now() - obj.tombstonedAt()! >= this._realtimeObject.gcGracePeriod\r\n      ) {\r\n        toDelete.push(objectId);\r\n        continue;\r\n      }\r\n\r\n      obj.onGCInterval();\r\n    }\r\n\r\n    toDelete.forEach((x) => this._pool.delete(x));\r\n  }\r\n}\r\n", "import type BaseClient from 'common/lib/client/baseclient';\nimport type {\n  AnyBatchContext,\n  BatchContext,\n  CompactedJsonValue,\n  CompactedValue,\n  Instance,\n  Primitive,\n  Value,\n} from '../../../liveobjects';\nimport { DefaultInstance } from './instance';\nimport { LiveCounter } from './livecounter';\nimport { LiveMap } from './livemap';\nimport { RealtimeObject } from './realtimeobject';\nimport { RootBatchContext } from './rootbatchcontext';\n\nexport class DefaultBatchContext implements AnyBatchContext {\n  protected _client: BaseClient;\n\n  constructor(\n    protected _realtimeObject: RealtimeObject,\n    protected _instance: Instance<Value>,\n    protected _rootContext: RootBatchContext,\n  ) {\n    this._client = this._realtimeObject.getClient();\n  }\n\n  get id(): string | undefined {\n    this._throwIfClosed();\n    return this._instance.id;\n  }\n\n  get<T extends Value = Value>(key: string): BatchContext<T> | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    const instance = this._instance.get(key);\n    if (!instance) {\n      return undefined;\n    }\n    return this._rootContext.wrapInstance(instance) as unknown as BatchContext<T>;\n  }\n\n  value<T extends Primitive = Primitive>(): T | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    return this._instance.value();\n  }\n\n  compact<T extends Value = Value>(): CompactedValue<T> | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    return this._instance.compact();\n  }\n\n  compactJson<T extends Value = Value>(): CompactedJsonValue<T> | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    return this._instance.compactJson();\n  }\n\n  *entries<T extends Record<string, Value>>(): IterableIterator<[keyof T, BatchContext<T[keyof T]>]> {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    for (const [key, value] of this._instance.entries()) {\n      const ctx = this._rootContext.wrapInstance(value) as unknown as BatchContext<T[keyof T]>;\n      yield [key, ctx];\n    }\n  }\n\n  *keys<T extends Record<string, Value>>(): IterableIterator<keyof T> {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    yield* this._instance.keys();\n  }\n\n  *values<T extends Record<string, Value>>(): IterableIterator<BatchContext<T[keyof T]>> {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    for (const [_, value] of this.entries<T>()) {\n      yield value;\n    }\n  }\n\n  size(): number | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n    this._throwIfClosed();\n    return this._instance.size();\n  }\n\n  set(key: string, value: Value): void {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    this._throwIfClosed();\n    if (!(this._instance as DefaultInstance<Value>).isLiveMap()) {\n      throw new this._client.ErrorInfo('Cannot set a key on a non-LiveMap instance', 92007, 400);\n    }\n    this._rootContext.queueMessages(async () =>\n      LiveMap.createMapSetMessage(this._realtimeObject, this._instance.id!, key, value),\n    );\n  }\n\n  remove(key: string): void {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    this._throwIfClosed();\n    if (!(this._instance as DefaultInstance<Value>).isLiveMap()) {\n      throw new this._client.ErrorInfo('Cannot remove a key from a non-LiveMap instance', 92007, 400);\n    }\n    this._rootContext.queueMessages(async () => [\n      LiveMap.createMapRemoveMessage(this._realtimeObject, this._instance.id!, key),\n    ]);\n  }\n\n  increment(amount?: number): void {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    this._throwIfClosed();\n    if (!(this._instance as DefaultInstance<Value>).isLiveCounter()) {\n      throw new this._client.ErrorInfo('Cannot increment a non-LiveCounter instance', 92007, 400);\n    }\n    this._rootContext.queueMessages(async () => [\n      LiveCounter.createCounterIncMessage(this._realtimeObject, this._instance.id!, amount ?? 1),\n    ]);\n  }\n\n  decrement(amount?: number): void {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    this._throwIfClosed();\n    if (!(this._instance as DefaultInstance<Value>).isLiveCounter()) {\n      throw new this._client.ErrorInfo('Cannot decrement a non-LiveCounter instance', 92007, 400);\n    }\n    this.increment(-(amount ?? 1));\n  }\n\n  private _throwIfClosed(): void {\n    if (this._rootContext.isClosed()) {\n      throw new this._client.ErrorInfo('Batch is closed', 40000, 400);\n    }\n  }\n}\n", "import type { Instance, Value } from '../../../liveobjects';\nimport { DefaultBatchContext } from './batchcontext';\nimport { ObjectMessage } from './objectmessage';\nimport { RealtimeObject } from './realtimeobject';\n\nexport class RootBatchContext extends DefaultBatchContext {\n  /** Maps object ids to the corresponding batch context wrappers  */\n  private _wrappedInstances: Map<string, DefaultBatchContext> = new Map();\n  /**\n   * Some object messages require asynchronous I/O during construction\n   * (for example, generating an objectId for nested value types).\n   * Therefore, messages cannot be constructed immediately during\n   * synchronous method calls from batch context methods.\n   * Instead, message constructors are queued and executed on flush.\n   */\n  private _queuedMessageConstructors: (() => Promise<ObjectMessage[]>)[] = [];\n  private _isClosed = false;\n\n  constructor(realtimeObject: RealtimeObject, instance: Instance<Value>) {\n    // Pass a placeholder null that will be replaced immediately\n    super(realtimeObject, instance, null as any);\n    // Set the root context to itself\n    this._rootContext = this;\n  }\n\n  /** @internal */\n  async flush(): Promise<void> {\n    try {\n      this.close();\n\n      const msgs = (await Promise.all(this._queuedMessageConstructors.map((x) => x()))).flat();\n\n      if (msgs.length > 0) {\n        await this._realtimeObject.publishAndApply(msgs);\n      }\n    } finally {\n      this._wrappedInstances.clear();\n      this._queuedMessageConstructors = [];\n    }\n  }\n\n  /** @internal */\n  close(): void {\n    this._isClosed = true;\n  }\n\n  /** @internal */\n  isClosed(): boolean {\n    return this._isClosed;\n  }\n\n  /** @internal */\n  wrapInstance(instance: Instance<Value>): DefaultBatchContext {\n    const objectId = instance.id;\n    if (objectId) {\n      // memoize liveobject instances by their object ids\n      if (this._wrappedInstances.has(objectId)) {\n        return this._wrappedInstances.get(objectId)!;\n      }\n\n      let wrappedInstance = new DefaultBatchContext(this._realtimeObject, instance, this);\n      this._wrappedInstances.set(objectId, wrappedInstance);\n      return wrappedInstance;\n    }\n\n    return new DefaultBatchContext(this._realtimeObject, instance, this);\n  }\n\n  /** @internal */\n  queueMessages(msgCtors: () => Promise<ObjectMessage[]>): void {\n    this._queuedMessageConstructors.push(msgCtors);\n  }\n}\n", "import type BaseClient from 'common/lib/client/baseclient';\nimport type { EventCallback, Subscription } from '../../../ably';\nimport type {\n  AnyInstance,\n  BatchContext,\n  BatchFunction,\n  CompactedJsonValue,\n  CompactedValue,\n  Instance,\n  InstanceSubscriptionEvent,\n  LiveObject as LiveObjectType,\n  Primitive,\n  Value,\n} from '../../../liveobjects';\nimport { LiveCounter } from './livecounter';\nimport { LiveMap } from './livemap';\nimport { LiveObject } from './liveobject';\nimport { ObjectMessage } from './objectmessage';\nimport { RealtimeObject } from './realtimeobject';\nimport { RootBatchContext } from './rootbatchcontext';\n\nexport interface InstanceEvent {\n  /** Object message that caused this event */\n  message?: ObjectMessage;\n}\n\nexport class DefaultInstance<T extends Value> implements AnyInstance<T> {\n  protected _client: BaseClient;\n\n  constructor(\n    private _realtimeObject: RealtimeObject,\n    private _value: T,\n  ) {\n    this._client = this._realtimeObject.getClient();\n  }\n\n  get id(): string | undefined {\n    if (!(this._value instanceof LiveObject)) {\n      // no id exists for non-LiveObject types\n      return undefined;\n    }\n    return this._value.getObjectId();\n  }\n\n  /**\n   * Returns an in-memory JavaScript object representation of this instance.\n   * Buffers are returned as-is.\n   * For primitive types, this is an alias for calling value().\n   *\n   * Use compactJson() for a JSON-serializable representation.\n   */\n  compact<U extends Value = Value>(): CompactedValue<U> | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (this._value instanceof LiveMap) {\n      return this._value.compact() as CompactedValue<U>;\n    }\n\n    return this.value() as CompactedValue<U>;\n  }\n\n  /**\n   * Returns a JSON-serializable representation of this instance.\n   * Buffers are converted to base64 strings.\n   *\n   * Use compact() for an in-memory representation.\n   */\n  compactJson<U extends Value = Value>(): CompactedJsonValue<U> | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (this._value instanceof LiveMap) {\n      return this._value.compactJson() as CompactedJsonValue<U>;\n    }\n\n    const value = this.value();\n\n    if (this._client.Platform.BufferUtils.isBuffer(value)) {\n      return this._client.Platform.BufferUtils.base64Encode(value) as CompactedJsonValue<U>;\n    }\n\n    return value as CompactedJsonValue<U>;\n  }\n\n  get<U extends Value = Value>(key: string): Instance<U> | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (!(this._value instanceof LiveMap)) {\n      // can't get a key from a non-LiveMap type\n      return undefined;\n    }\n\n    if (typeof key !== 'string') {\n      throw new this._client.ErrorInfo(`Key must be a string: ${key}`, 40003, 400);\n    }\n\n    const value = this._value.get(key);\n    if (value === undefined) {\n      return undefined;\n    }\n    return new DefaultInstance<U>(this._realtimeObject, value) as unknown as Instance<U>;\n  }\n\n  value<U extends number | Primitive = number | Primitive>(): U | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (this._value instanceof LiveObject) {\n      if (this._value instanceof LiveCounter) {\n        return this._value.value() as U;\n      }\n\n      // for other LiveObject types, return undefined\n      return undefined;\n    } else if (\n      this._client.Platform.BufferUtils.isBuffer(this._value) ||\n      typeof this._value === 'string' ||\n      typeof this._value === 'number' ||\n      typeof this._value === 'boolean' ||\n      typeof this._value === 'object' ||\n      this._value === null\n    ) {\n      // primitive type - return it\n      return this._value as unknown as U;\n    } else {\n      this._client.Logger.logAction(\n        this._client.logger,\n        this._client.Logger.LOG_MAJOR,\n        'DefaultInstance.value()',\n        `unexpected value type for instance, resolving to undefined; value=${this._value}; type=${typeof this._value}`,\n      );\n      // unknown type - return undefined\n      return undefined;\n    }\n  }\n\n  *entries<U extends Record<string, Value>>(): IterableIterator<[keyof U, Instance<U[keyof U]>]> {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (!(this._value instanceof LiveMap)) {\n      // return empty iterator for non-LiveMap objects\n      return;\n    }\n\n    for (const [key, value] of this._value.entries()) {\n      const instance = new DefaultInstance<U[keyof U]>(this._realtimeObject, value) as unknown as Instance<U[keyof U]>;\n      yield [key, instance];\n    }\n  }\n\n  *keys<U extends Record<string, Value>>(): IterableIterator<keyof U> {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (!(this._value instanceof LiveMap)) {\n      // return empty iterator for non-LiveMap objects\n      return;\n    }\n\n    yield* this._value.keys();\n  }\n\n  *values<U extends Record<string, Value>>(): IterableIterator<Instance<U[keyof U]>> {\n    for (const [_, value] of this.entries<U>()) {\n      yield value;\n    }\n  }\n\n  size(): number | undefined {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (!(this._value instanceof LiveMap)) {\n      // can't return size for non-LiveMap objects\n      return undefined;\n    }\n    return this._value.size();\n  }\n\n  set<U extends Record<string, Value> = Record<string, Value>>(\n    key: keyof U & string,\n    value: U[keyof U],\n  ): Promise<void> {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    if (!(this._value instanceof LiveMap)) {\n      throw new this._client.ErrorInfo('Cannot set a key on a non-LiveMap instance', 92007, 400);\n    }\n    return this._value.set(key, value);\n  }\n\n  remove<U extends Record<string, Value> = Record<string, Value>>(key: keyof U & string): Promise<void> {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    if (!(this._value instanceof LiveMap)) {\n      throw new this._client.ErrorInfo('Cannot remove a key from a non-LiveMap instance', 92007, 400);\n    }\n    return this._value.remove(key);\n  }\n\n  increment(amount?: number | undefined): Promise<void> {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    if (!(this._value instanceof LiveCounter)) {\n      throw new this._client.ErrorInfo('Cannot increment a non-LiveCounter instance', 92007, 400);\n    }\n    return this._value.increment(amount ?? 1);\n  }\n\n  decrement(amount?: number | undefined): Promise<void> {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n    if (!(this._value instanceof LiveCounter)) {\n      throw new this._client.ErrorInfo('Cannot decrement a non-LiveCounter instance', 92007, 400);\n    }\n    return this._value.decrement(amount ?? 1);\n  }\n\n  subscribe(listener: EventCallback<InstanceSubscriptionEvent<T>>): Subscription {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (!(this._value instanceof LiveObject)) {\n      throw new this._client.ErrorInfo('Cannot subscribe to a non-LiveObject instance', 92007, 400);\n    }\n\n    return this._value.subscribe((event: InstanceEvent) => {\n      listener({\n        object: this as unknown as Instance<T>,\n        message: event.message?.toUserFacingMessage(this._realtimeObject.getChannel()),\n      });\n    });\n  }\n\n  subscribeIterator(): AsyncIterableIterator<InstanceSubscriptionEvent<T>> {\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\n\n    if (!(this._value instanceof LiveObject)) {\n      throw new this._client.ErrorInfo('Cannot subscribe to a non-LiveObject instance', 92007, 400);\n    }\n\n    return this._client.Utils.listenerToAsyncIterator((listener) => {\n      const { unsubscribe } = this.subscribe(listener);\n      return unsubscribe;\n    });\n  }\n\n  async batch<T extends LiveObjectType = LiveObjectType>(fn: BatchFunction<T>): Promise<void> {\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\n\n    if (!(this._value instanceof LiveObject)) {\n      throw new this._client.ErrorInfo('Cannot batch operations on a non-LiveObject instance', 92007, 400);\n    }\n\n    const ctx = new RootBatchContext(this._realtimeObject, this);\n    try {\n      fn(ctx as unknown as BatchContext<T>);\n      await ctx.flush();\n    } finally {\n      ctx.close();\n    }\n  }\n\n  /** @internal */\n  public isLiveMap(): boolean {\n    return this._value instanceof LiveMap;\n  }\n\n  /** @internal */\n  public isLiveCounter(): boolean {\n    return this._value instanceof LiveCounter;\n  }\n}\n", "import type BaseClient from 'common/lib/client/baseclient';\r\nimport type { EventCallback, Subscription } from '../../../ably';\r\nimport type {\r\n  AnyPathObject,\r\n  BatchContext,\r\n  BatchFunction,\r\n  CompactedJsonValue,\r\n  CompactedValue,\r\n  Instance,\r\n  LiveObject as LiveObjectType,\r\n  PathObject,\r\n  PathObjectSubscriptionEvent,\r\n  PathObjectSubscriptionOptions,\r\n  Primitive,\r\n  Value,\r\n} from '../../../liveobjects';\r\nimport { DefaultInstance } from './instance';\r\nimport { LiveCounter } from './livecounter';\r\nimport { LiveMap } from './livemap';\r\nimport { LiveObject } from './liveobject';\r\nimport { Path } from './path';\r\nimport { RealtimeObject } from './realtimeobject';\r\nimport { RootBatchContext } from './rootbatchcontext';\r\n\r\n/**\r\n * Implementation of AnyPathObject interface.\r\n * Provides a generic implementation that can handle any type of PathObject operations.\r\n */\r\nexport class DefaultPathObject implements AnyPathObject {\r\n  private _client: BaseClient;\r\n  private _path: Path;\r\n\r\n  constructor(\r\n    private _realtimeObject: RealtimeObject,\r\n    private _root: LiveMap,\r\n    path: Path,\r\n    parent?: DefaultPathObject,\r\n  ) {\r\n    this._client = this._realtimeObject.getClient();\r\n    // copy parent path array\r\n    this._path = [...(parent?._path ?? []), ...path];\r\n  }\r\n\r\n  /**\r\n   * Returns the fully-qualified string path that this PathObject represents.\r\n   * Path segments with dots in them are escaped with a backslash.\r\n   * For example, a path with segments `['a', 'b.c', 'd']` will be represented as `a.b\\.c.d`.\r\n   */\r\n  path(): string {\r\n    // escape dots in path segments to avoid ambiguity in the joined path\r\n    return this._escapePath(this._path).join('.');\r\n  }\r\n\r\n  /**\r\n   * Returns an in-memory JavaScript object representation of the object at this path.\r\n   * If the path does not resolve to any specific entry, returns `undefined`.\r\n   * Buffers are returned as-is.\r\n   * For primitive types, this is an alias for calling value().\r\n   *\r\n   * Use compactJson() for a JSON-serializable representation.\r\n   */\r\n  compact<U extends Value = Value>(): CompactedValue<U> | undefined {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n\r\n    try {\r\n      const resolved = this._resolvePath(this._path);\r\n\r\n      if (resolved instanceof LiveMap) {\r\n        return resolved.compact() as CompactedValue<U>;\r\n      }\r\n\r\n      return this.value() as CompactedValue<U>;\r\n    } catch (error) {\r\n      if (this._client.Utils.isErrorInfoOrPartialErrorInfo(error) && error.code === 92005) {\r\n        // ignore path resolution errors and return undefined\r\n        return undefined;\r\n      }\r\n      // rethrow everything else\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns a JSON-serializable representation of the object at this path.\r\n   * If the path does not resolve to any specific entry, returns `undefined`.\r\n   * Buffers are converted to base64 strings.\r\n   *\r\n   * Use compact() for an in-memory representation.\r\n   */\r\n  compactJson<U extends Value = Value>(): CompactedJsonValue<U> | undefined {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n\r\n    try {\r\n      const resolved = this._resolvePath(this._path);\r\n\r\n      if (resolved instanceof LiveMap) {\r\n        return resolved.compactJson() as CompactedJsonValue<U>;\r\n      }\r\n\r\n      const value = this.value();\r\n\r\n      if (this._client.Platform.BufferUtils.isBuffer(value)) {\r\n        return this._client.Platform.BufferUtils.base64Encode(value) as CompactedJsonValue<U>;\r\n      }\r\n\r\n      return value as CompactedJsonValue<U>;\r\n    } catch (error) {\r\n      if (this._client.Utils.isErrorInfoOrPartialErrorInfo(error) && error.code === 92005) {\r\n        // ignore path resolution errors and return undefined\r\n        return undefined;\r\n      }\r\n      // rethrow everything else\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Navigate to a child path within the collection by obtaining a PathObject for that path.\r\n   * The next path segment in a collection is identified with a string key.\r\n   */\r\n  get<U extends Value = Value>(key: string): PathObject<U> {\r\n    if (typeof key !== 'string') {\r\n      throw new this._client.ErrorInfo(`Path key must be a string: ${key}`, 40003, 400);\r\n    }\r\n    return new DefaultPathObject(this._realtimeObject, this._root, [key], this) as unknown as PathObject<U>;\r\n  }\r\n\r\n  /**\r\n   * Get a PathObject at the specified path relative to this object\r\n   */\r\n  at<U extends Value = Value>(path: string): PathObject<U> {\r\n    if (typeof path !== 'string') {\r\n      throw new this._client.ErrorInfo(`Path must be a string: ${path}`, 40003, 400);\r\n    }\r\n\r\n    // We need to split the path on unescaped dots, i.e. dots not preceded by a backslash.\r\n    // The easy way to do this would be to use \"path.split(/(?<!\\\\)\\./)\" to split on unescaped dots\r\n    // and then call \".replace(/\\\\\\./g, '.')\" on each segment.\r\n    // However, that uses negative lookbehind which is not supported in some browsers we aim to support\r\n    // (based on https://github.com/ably/ably-js/pull/2037/files), like Safari before 16.4.\r\n    // See full list https://caniuse.com/?search=negative%20lookbehind.\r\n    // So instead we do splitting manually.\r\n    const pathAsArray: Path = [];\r\n    let currentSegment = '';\r\n    let escaping = false;\r\n    for (const char of path) {\r\n      if (escaping) {\r\n        // keep the escape character if not escaping a dot\r\n        // this is to replicate the \".replace(/\\\\\\./g, '.')\" behavior where only escaped dots are unescaped\r\n        if (char !== '.') currentSegment += '\\\\';\r\n        currentSegment += char;\r\n        escaping = false;\r\n        continue;\r\n      }\r\n      if (char === '\\\\') {\r\n        escaping = true;\r\n        continue;\r\n      }\r\n      if (char === '.') {\r\n        pathAsArray.push(currentSegment);\r\n        currentSegment = '';\r\n        continue;\r\n      }\r\n      currentSegment += char;\r\n    }\r\n    if (escaping) {\r\n      currentSegment += '\\\\';\r\n    }\r\n    pathAsArray.push(currentSegment);\r\n\r\n    return new DefaultPathObject(this._realtimeObject, this._root, pathAsArray, this) as unknown as PathObject<U>;\r\n  }\r\n\r\n  /**\r\n   * Get the current value at this path.\r\n   * If the path does not resolve to any specific entry, returns `undefined`.\r\n   */\r\n  value<U extends number | Primitive = number | Primitive>(): U | undefined {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n\r\n    try {\r\n      const resolved = this._resolvePath(this._path);\r\n\r\n      if (resolved instanceof LiveObject) {\r\n        if (resolved instanceof LiveCounter) {\r\n          return resolved.value() as U;\r\n        }\r\n\r\n        // can't resolve value for other live object types\r\n        return undefined;\r\n      } else if (\r\n        this._client.Platform.BufferUtils.isBuffer(resolved) ||\r\n        typeof resolved === 'string' ||\r\n        typeof resolved === 'number' ||\r\n        typeof resolved === 'boolean' ||\r\n        typeof resolved === 'object' ||\r\n        resolved === null\r\n      ) {\r\n        // primitive type - return it\r\n        return resolved as U;\r\n      } else {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MAJOR,\r\n          'PathObject.value()',\r\n          `unexpected value type at path, resolving to undefined; path=${this._escapePath(this._path).join('.')}`,\r\n        );\r\n        // unknown type - return undefined\r\n        return undefined;\r\n      }\r\n    } catch (error) {\r\n      if (this._client.Utils.isErrorInfoOrPartialErrorInfo(error) && error.code === 92005) {\r\n        // ignore path resolution errors and return undefined\r\n        return undefined;\r\n      }\r\n      // rethrow everything else\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Get an Instance wrapping the value currently at this path, whether it is a LiveObject or a primitive.\r\n   * If the path does not resolve, returns `undefined`.\r\n   */\r\n  instance<T extends Value = Value>(): Instance<T> | undefined {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n\r\n    try {\r\n      return this._resolveInstance<T>();\r\n    } catch (error) {\r\n      if (this._client.Utils.isErrorInfoOrPartialErrorInfo(error) && error.code === 92005) {\r\n        // ignore path resolution errors and return undefined\r\n        return undefined;\r\n      }\r\n      // rethrow everything else\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns an iterator of [key, value] pairs for LiveMap entries\r\n   */\r\n  *entries<U extends Record<string, Value>>(): IterableIterator<[keyof U, PathObject<U[keyof U]>]> {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n\r\n    try {\r\n      const resolved = this._resolvePath(this._path);\r\n      if (!(resolved instanceof LiveMap)) {\r\n        // return empty iterator for non-LiveMap objects\r\n        return;\r\n      }\r\n\r\n      for (const [key, _] of resolved.entries()) {\r\n        const value = new DefaultPathObject(this._realtimeObject, this._root, [key], this) as unknown as PathObject<\r\n          U[keyof U]\r\n        >;\r\n        yield [key, value];\r\n      }\r\n    } catch (error) {\r\n      if (this._client.Utils.isErrorInfoOrPartialErrorInfo(error) && error.code === 92005) {\r\n        // ignore path resolution errors and return empty iterator\r\n        return;\r\n      }\r\n      // rethrow everything else\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns an iterator of keys for LiveMap entries\r\n   */\r\n  *keys<U extends Record<string, Value>>(): IterableIterator<keyof U> {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n\r\n    try {\r\n      const resolved = this._resolvePath(this._path);\r\n      if (!(resolved instanceof LiveMap)) {\r\n        // return empty iterator for non-LiveMap objects\r\n        return;\r\n      }\r\n\r\n      yield* resolved.keys();\r\n    } catch (error) {\r\n      if (this._client.Utils.isErrorInfoOrPartialErrorInfo(error) && error.code === 92005) {\r\n        // ignore path resolution errors and return empty iterator\r\n        return;\r\n      }\r\n      // rethrow everything else\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns an iterator of PathObject values for LiveMap entries\r\n   */\r\n  *values<U extends Record<string, Value>>(): IterableIterator<PathObject<U[keyof U]>> {\r\n    for (const [_, value] of this.entries<U>()) {\r\n      yield value;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns the size of the collection at this path\r\n   */\r\n  size(): number | undefined {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n\r\n    try {\r\n      const resolved = this._resolvePath(this._path);\r\n      if (!(resolved instanceof LiveMap)) {\r\n        // can't return size for non-LiveMap objects\r\n        return undefined;\r\n      }\r\n\r\n      return resolved.size();\r\n    } catch (error) {\r\n      if (this._client.Utils.isErrorInfoOrPartialErrorInfo(error) && error.code === 92005) {\r\n        // ignore path resolution errors and return undefined\r\n        return undefined;\r\n      }\r\n      // rethrow everything else\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  set<T extends Record<string, Value> = Record<string, Value>>(\r\n    key: keyof T & string,\r\n    value: T[keyof T],\r\n  ): Promise<void> {\r\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\r\n\r\n    const resolved = this._resolvePath(this._path);\r\n    if (!(resolved instanceof LiveMap)) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot set a key on a non-LiveMap object at path: ${this._escapePath(this._path).join('.')}`,\r\n        92007,\r\n        400,\r\n      );\r\n    }\r\n\r\n    return resolved.set(key, value);\r\n  }\r\n\r\n  remove<T extends Record<string, Value> = Record<string, Value>>(key: keyof T & string): Promise<void> {\r\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\r\n\r\n    const resolved = this._resolvePath(this._path);\r\n    if (!(resolved instanceof LiveMap)) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot remove a key from a non-LiveMap object at path: ${this._escapePath(this._path).join('.')}`,\r\n        92007,\r\n        400,\r\n      );\r\n    }\r\n\r\n    return resolved.remove(key);\r\n  }\r\n\r\n  increment(amount?: number): Promise<void> {\r\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\r\n\r\n    const resolved = this._resolvePath(this._path);\r\n    if (!(resolved instanceof LiveCounter)) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot increment a non-LiveCounter object at path: ${this._escapePath(this._path).join('.')}`,\r\n        92007,\r\n        400,\r\n      );\r\n    }\r\n\r\n    return resolved.increment(amount ?? 1);\r\n  }\r\n\r\n  decrement(amount?: number): Promise<void> {\r\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\r\n\r\n    const resolved = this._resolvePath(this._path);\r\n    if (!(resolved instanceof LiveCounter)) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot decrement a non-LiveCounter object at path: ${this._escapePath(this._path).join('.')}`,\r\n        92007,\r\n        400,\r\n      );\r\n    }\r\n\r\n    return resolved.decrement(amount ?? 1);\r\n  }\r\n\r\n  /**\r\n   * Subscribes to changes to the object (and, by default, its children) or to a primitive value at this path.\r\n   *\r\n   * PathObject subscriptions rely on LiveObject instances to broadcast updates through a subscription\r\n   * registry for the paths they occupy in the object graph. These updates are then routed to the appropriate\r\n   * PathObject subscriptions based on their paths.\r\n   *\r\n   * When the underlying object or primitive value at this path is changed via an update to its parent\r\n   * collection (for example, if a new LiveCounter instance is set at this path, or a key's value is\r\n   * changed in a parent LiveMap), a subscription to this path will receive a separate **non-bubbling**\r\n   * event indicating the change. This event is not propagated to parent path subscriptions, as they will\r\n   * receive their own event for changes made directly to the object at their respective paths.\r\n   *\r\n   * PathObject subscriptions observe nested changes by default. Optional `depth` parameter can be provided\r\n   * to control this behavior. A subscription depth of `1` means that only direct updates to the underlying\r\n   * object - and changes that overwrite the value at this path (via parent object updates) - will trigger events.\r\n   */\r\n\r\n  subscribe(\r\n    listener: EventCallback<PathObjectSubscriptionEvent>,\r\n    options?: PathObjectSubscriptionOptions,\r\n  ): Subscription {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n    return this._realtimeObject.getPathObjectSubscriptionRegister().subscribe(this._path, listener, options ?? {});\r\n  }\r\n\r\n  subscribeIterator(options?: PathObjectSubscriptionOptions): AsyncIterableIterator<PathObjectSubscriptionEvent> {\r\n    this._realtimeObject.throwIfInvalidAccessApiConfiguration();\r\n    return this._client.Utils.listenerToAsyncIterator((listener) => {\r\n      const { unsubscribe } = this.subscribe(listener, options);\r\n      return unsubscribe;\r\n    });\r\n  }\r\n\r\n  async batch<T extends LiveObjectType = LiveObjectType>(fn: BatchFunction<T>): Promise<void> {\r\n    this._realtimeObject.throwIfInvalidWriteApiConfiguration();\r\n\r\n    // a path may resolve to a primitive (RTPO8f), but only LiveObjects can host batch operations\r\n    const resolved = this._resolvePath(this._path);\r\n    if (!(resolved instanceof LiveObject)) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot batch operations on a non-LiveObject at path: ${this._escapePath(this._path).join('.')}`,\r\n        92007,\r\n        400,\r\n      );\r\n    }\r\n\r\n    const instance = new DefaultInstance(this._realtimeObject, resolved) as unknown as Instance<Value>;\r\n    const ctx = new RootBatchContext(this._realtimeObject, instance);\r\n    try {\r\n      fn(ctx as unknown as BatchContext<T>);\r\n      await ctx.flush();\r\n    } finally {\r\n      ctx.close();\r\n    }\r\n  }\r\n\r\n  private _resolvePath(path: Path): Value {\r\n    let current: Value = this._root;\r\n\r\n    for (let i = 0; i < path.length; i++) {\r\n      const segment = path[i];\r\n\r\n      if (!(current instanceof LiveMap)) {\r\n        throw new this._client.ErrorInfo(\r\n          `Cannot resolve path segment '${segment}' on non-collection type at path: ${this._escapePath(path.slice(0, i)).join('.')}`,\r\n          92005,\r\n          400,\r\n        );\r\n      }\r\n\r\n      const next: Value | undefined = current.get(segment);\r\n\r\n      if (next === undefined) {\r\n        throw new this._client.ErrorInfo(\r\n          `Could not resolve value at path: ${this._escapePath(path.slice(0, i + 1)).join('.')}`,\r\n          92005,\r\n          400,\r\n        );\r\n      }\r\n\r\n      current = next;\r\n    }\r\n\r\n    return current;\r\n  }\r\n\r\n  private _resolveInstance<T extends Value = Value>(): Instance<T> {\r\n    const value = this._resolvePath(this._path);\r\n\r\n    // wrap the resolved value in an Instance, whether a LiveObject or a primitive (RTPO8c, RTPO8f)\r\n    return new DefaultInstance(this._realtimeObject, value) as unknown as Instance<T>;\r\n  }\r\n\r\n  private _escapePath(path: Path): Path {\r\n    return path.map((x) => x.replace(/\\./g, '\\\\.'));\r\n  }\r\n}\r\n", "import type BaseClient from 'common/lib/client/baseclient';\r\nimport type { EventCallback, Subscription } from '../../../ably';\r\nimport type { PathObjectSubscriptionEvent, PathObjectSubscriptionOptions } from '../../../liveobjects';\r\nimport { ObjectMessage } from './objectmessage';\r\nimport { Path } from './path';\r\nimport { DefaultPathObject } from './pathobject';\r\nimport { RealtimeObject } from './realtimeobject';\r\n\r\n/**\r\n * Internal subscription entry that tracks a listener and its options\r\n */\r\nexport interface SubscriptionEntry {\r\n  /** The listener function to call when events match */\r\n  listener: EventCallback<PathObjectSubscriptionEvent>;\r\n  /** The subscription options including depth */\r\n  options: PathObjectSubscriptionOptions;\r\n  /** The path this subscription is registered for */\r\n  path: Path;\r\n}\r\n\r\n/**\r\n * Event data that LiveObjects provide when notifying of changes\r\n */\r\nexport interface PathEvent {\r\n  /**\r\n   * Candidate paths for surfacing this event to subscriptions, in order of\r\n   * decreasing preference. For a given subscription, the first candidate path\r\n   * it covers is used as the path of `event.object` passed to its listener.\r\n   */\r\n  preferenceOrderedCandidatePaths: Path[];\r\n  /** Object message that caused this event */\r\n  message?: ObjectMessage;\r\n}\r\n\r\n/**\r\n * Registry for managing PathObject subscriptions and routing events to appropriate listeners.\r\n * Handles depth-based filtering for subscription matching.\r\n *\r\n * @internal\r\n */\r\nexport class PathObjectSubscriptionRegister {\r\n  private _client: BaseClient;\r\n  private _subscriptions: Map<string, SubscriptionEntry> = new Map();\r\n  private _nextSubscriptionId = 0;\r\n\r\n  constructor(private _realtimeObject: RealtimeObject) {\r\n    this._client = this._realtimeObject.getClient();\r\n  }\r\n\r\n  /**\r\n   * Registers a new subscription for the given path.\r\n   *\r\n   * @param path - Array of keys representing the path to subscribe to\r\n   * @param listener - Function to call when matching events occur\r\n   * @param options - Subscription options including depth parameter\r\n   * @returns Unsubscribe function\r\n   */\r\n  subscribe(\r\n    path: Path,\r\n    listener: EventCallback<PathObjectSubscriptionEvent>,\r\n    options: PathObjectSubscriptionOptions,\r\n  ): Subscription {\r\n    if (options == null || typeof options !== 'object') {\r\n      throw new this._client.ErrorInfo('Subscription options must be an object', 40000, 400);\r\n    }\r\n\r\n    if (options.depth !== undefined && options.depth <= 0) {\r\n      throw new this._client.ErrorInfo(\r\n        'Subscription depth must be greater than 0 or undefined for infinite depth',\r\n        40003,\r\n        400,\r\n      );\r\n    }\r\n\r\n    const subscriptionId = (this._nextSubscriptionId++).toString();\r\n    const entry: SubscriptionEntry = {\r\n      listener,\r\n      options,\r\n      path: [...path], // Make a copy to avoid external mutations\r\n    };\r\n\r\n    this._subscriptions.set(subscriptionId, entry);\r\n\r\n    return {\r\n      unsubscribe: () => {\r\n        this._subscriptions.delete(subscriptionId);\r\n      },\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Dispatches a {@link PathEvent} to subscriptions. Each subscription that\r\n   * covers any of the event's {@link PathEvent.preferenceOrderedCandidatePaths}\r\n   * receives at most one notification, at the first covered path.\r\n   */\r\n  notifyPathEvent(event: PathEvent): void {\r\n    for (const subscription of this._subscriptions.values()) {\r\n      const chosenCoveredPath = event.preferenceOrderedCandidatePaths.find((path) =>\r\n        this._subscriptionCoversPath(subscription, path),\r\n      );\r\n      if (chosenCoveredPath === undefined) {\r\n        continue;\r\n      }\r\n\r\n      try {\r\n        const subscriptionEvent: PathObjectSubscriptionEvent = {\r\n          object: new DefaultPathObject(\r\n            this._realtimeObject,\r\n            this._realtimeObject.getPool().getRoot(),\r\n            chosenCoveredPath,\r\n          ),\r\n          message: event.message?.toUserFacingMessage(this._realtimeObject.getChannel()),\r\n        };\r\n\r\n        subscription.listener(subscriptionEvent);\r\n      } catch (error) {\r\n        // Log error but don't let one subscription failure affect others\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MINOR,\r\n          'PathObjectSubscriptionRegister.notifyPathEvent()',\r\n          `Error in PathObject subscription listener; path=${JSON.stringify(chosenCoveredPath)}, error=${error}`,\r\n        );\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns true if the given path falls within the area covered by the\r\n   * subscription \u2014 that is, it starts with the subscription's path, and\r\n   * extends it by at most `depth \u2212 1` further segments.\r\n   *\r\n   * Coverage examples:\r\n   * - subscription at [\"users\"] with depth=undefined: covers [\"users\"], [\"users\", \"emma\"], [\"users\", \"emma\", \"visits\"], etc.\r\n   * - subscription at [\"users\"] with depth=1: covers [\"users\"] only\r\n   * - subscription at [\"users\"] with depth=2: covers [\"users\"], [\"users\", \"emma\"] only\r\n   * - subscription at [\"users\"] with depth=3: covers [\"users\"], [\"users\", \"emma\"], [\"users\", \"emma\", \"visits\"] only\r\n   *\r\n   * The depth calculation is: eventPath.length - subscriptionPath.length + 1\r\n   * This means:\r\n   * - Same level ([\"users\"] -> [\"users\"]): 1 - 1 + 1 = 1 (depth=1)\r\n   * - One level deeper ([\"users\"] -> [\"users\", \"emma\"]): 2 - 1 + 1 = 2 (depth=2)\r\n   * - Two levels deeper ([\"users\"] -> [\"users\", \"emma\", \"visits\"]): 3 - 1 + 1 = 3 (depth=3)\r\n   */\r\n  private _subscriptionCoversPath(subscription: SubscriptionEntry, eventPath: Path): boolean {\r\n    const subPath = subscription.path;\r\n    const depth = subscription.options.depth;\r\n\r\n    // Check if the event path starts with the subscription path\r\n    if (!this._pathStartsWith(eventPath, subPath)) {\r\n      return false;\r\n    }\r\n\r\n    // If depth is undefined, allow infinite depth\r\n    if (depth === undefined) {\r\n      return true;\r\n    }\r\n\r\n    // Otherwise calculate the relative depth from subscription path to event path\r\n    const relativeDepth = eventPath.length - subPath.length + 1;\r\n\r\n    // Check if the event is within the allowed depth\r\n    return relativeDepth <= depth;\r\n  }\r\n\r\n  /**\r\n   * Checks if eventPath starts with subscriptionPath.\r\n   *\r\n   * @param eventPath - The path where the event occurred\r\n   * @param subscriptionPath - The path that was subscribed to\r\n   * @returns true if eventPath starts with subscriptionPath\r\n   */\r\n  private _pathStartsWith(eventPath: Path, subscriptionPath: Path): boolean {\r\n    if (subscriptionPath.length > eventPath.length) {\r\n      return false;\r\n    }\r\n\r\n    for (let i = 0; i < subscriptionPath.length; i++) {\r\n      if (eventPath[i] !== subscriptionPath[i]) {\r\n        return false;\r\n      }\r\n    }\r\n\r\n    return true;\r\n  }\r\n}\r\n", "import type BaseClient from 'common/lib/client/baseclient';\r\nimport type RealtimeChannel from 'common/lib/client/realtimechannel';\r\nimport { ObjectMessage } from './objectmessage';\r\nimport { RealtimeObject } from './realtimeobject';\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class SyncObjectsPool {\r\n  private _client: BaseClient;\r\n  private _channel: RealtimeChannel;\r\n  /** Used to accumulate object state during a sync sequence, keyed by object ID */\r\n  private _pool: Map<string, ObjectMessage>;\r\n\r\n  constructor(private _realtimeObject: RealtimeObject) {\r\n    this._client = this._realtimeObject.getClient();\r\n    this._channel = this._realtimeObject.getChannel();\r\n    this._pool = new Map<string, ObjectMessage>();\r\n  }\r\n\r\n  entries() {\r\n    return this._pool.entries();\r\n  }\r\n\r\n  size(): number {\r\n    return this._pool.size;\r\n  }\r\n\r\n  isEmpty(): boolean {\r\n    return this._pool.size === 0;\r\n  }\r\n\r\n  clear(): void {\r\n    this._pool.clear();\r\n  }\r\n\r\n  /** @spec RTO5f */\r\n  applyObjectSyncMessages(objectMessages: ObjectMessage[]): void {\r\n    for (const objectMessage of objectMessages) {\r\n      if (!objectMessage.object) {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MAJOR,\r\n          'SyncObjectsPool.applyObjectSyncMessages()',\r\n          `received OBJECT_SYNC message without 'object' field, skipping message; message id: ${objectMessage.id}, channel: ${this._channel.name}`,\r\n        );\r\n        continue;\r\n      }\r\n\r\n      const objectState = objectMessage.object;\r\n\r\n      if (!objectState.counter && !objectState.map) {\r\n        // RTO5f3\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MAJOR,\r\n          'SyncObjectsPool.applyObjectSyncMessages()',\r\n          `received OBJECT_SYNC message with unsupported object type, expected 'counter' or 'map' to be present, skipping message; message id: ${objectMessage.id}, channel: ${this._channel.name}`,\r\n        );\r\n        continue;\r\n      }\r\n\r\n      const objectId = objectState.objectId;\r\n      const existingEntry = this._pool.get(objectId);\r\n\r\n      if (!existingEntry) {\r\n        // RTO5f1 - no entry with this objectId exists yet, store it\r\n        this._pool.set(objectId, objectMessage);\r\n        continue;\r\n      }\r\n\r\n      // RTO5f2 - an object is split across multiple sync messages, merge the new state with the existing entry in the pool based on the object type\r\n      if (objectState.counter) {\r\n        // RTO5f2b - counter objects have a bounded size and should never be split\r\n        // across multiple sync messages. Skip the unexpected partial state.\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_ERROR,\r\n          'SyncObjectsPool.applyObjectSyncMessages()',\r\n          `received partial OBJECT_SYNC state for a counter object, skipping message; object id: ${objectId}, message id: ${objectMessage.id}, channel: ${this._channel.name}`,\r\n        );\r\n        continue;\r\n      }\r\n\r\n      if (objectState.map) {\r\n        // RTO5f2a\r\n        this._mergeMapSyncState(existingEntry, objectMessage);\r\n        continue;\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Merges map entries from a partial sync message into an existing entry in the pool.\r\n   * @spec RTO5f2a\r\n   */\r\n  private _mergeMapSyncState(existingEntry: ObjectMessage, newObjectMessage: ObjectMessage): void {\r\n    const existingObjectState = existingEntry.object!;\r\n    const newObjectState = newObjectMessage.object!;\r\n\r\n    if (newObjectState.tombstone) {\r\n      // RTO5f2a1 - a tombstone flag on any partial message takes precedence over previously accumulated entries\r\n      this._pool.set(existingObjectState.objectId, newObjectMessage);\r\n      return;\r\n    }\r\n\r\n    // Other fields on the ObjectState envelope (such as siteTimeserials) and the map envelope\r\n    // (such as semantics) are identical across all partial messages for the same object,\r\n    // so only the entries need to be merged.\r\n    if (!existingObjectState.map!.entries) {\r\n      existingObjectState.map!.entries = {};\r\n    }\r\n\r\n    // RTO5f2a2 - during partial sync, no two messages contain the same map key,\r\n    // so entries can be merged directly without conflict checking.\r\n    Object.assign(existingObjectState.map!.entries, newObjectState.map!.entries);\r\n  }\r\n}\r\n", "import type BaseClient from 'common/lib/client/baseclient';\r\nimport type RealtimeChannel from 'common/lib/client/realtimechannel';\r\nimport type ErrorInfo from 'common/lib/types/errorinfo';\r\nimport type EventEmitter from 'common/lib/util/eventemitter';\r\nimport type * as API from '../../../ably';\r\nimport type { ChannelState, StatusSubscription } from '../../../ably';\r\nimport type * as ObjectsApi from '../../../liveobjects';\r\nimport { DEFAULTS } from './defaults';\r\nimport { LiveCounter } from './livecounter';\r\nimport { LiveMap } from './livemap';\r\nimport { LiveObject, LiveObjectUpdate, LiveObjectUpdateNoop } from './liveobject';\r\nimport { ObjectMessage, ObjectOperationAction } from './objectmessage';\r\nimport { ObjectsPool } from './objectspool';\r\nimport { DefaultPathObject } from './pathobject';\r\nimport { PathObjectSubscriptionRegister } from './pathobjectsubscriptionregister';\r\nimport { SyncObjectsPool } from './syncobjectspool';\r\n\r\nexport enum ObjectsEvent {\r\n  syncing = 'syncing',\r\n  synced = 'synced',\r\n}\r\n\r\n/**\r\n * Internal-only signals emitted on `_eventEmitterInternal` (never on `_eventEmitterPublic`), so they\r\n * are not observable through the public `RealtimeObject#on` API.\r\n */\r\nenum ObjectsInternalEvent {\r\n  // RTO23c1 / RTO20e1 - emitted when the channel transitions into DETACHED/SUSPENDED/FAILED, so that\r\n  // parked objects-sync waiters (get()/publishAndApply) can fail. Carries the channel state and its\r\n  // errorReason as emit arguments.\r\n  syncWaitFailed = 'syncWaitFailed',\r\n}\r\n\r\n/** @spec RTO22 */\r\nexport enum ObjectsOperationSource {\r\n  local = 'local',\r\n  channel = 'channel',\r\n}\r\n\r\nexport enum ObjectsState {\r\n  initialized = 'initialized',\r\n  syncing = 'syncing',\r\n  synced = 'synced',\r\n}\r\n\r\nconst StateToEventsMap: Record<ObjectsState, ObjectsEvent | undefined> = {\r\n  initialized: undefined,\r\n  syncing: ObjectsEvent.syncing,\r\n  synced: ObjectsEvent.synced,\r\n};\r\n\r\nexport type ObjectsEventCallback = () => void;\r\n\r\n/**\r\n * Remediation for a `get()` sync wait failing (RTO23c1). The rejection is recoverable, but the\r\n * recovery differs per state: `ensureAttached` at `get()` entry re-attaches a DETACHED channel\r\n * itself and proceeds through SUSPENDED (the SDK re-attaches when the connection recovers), so a\r\n * plain retry suffices for those two states, whereas from FAILED `get()` rejects at entry (90001)\r\n * until the channel is explicitly re-attached.\r\n */\r\nfunction getSyncWaitFailureRemediation(state: ChannelState): string {\r\n  switch (state) {\r\n    case 'detached':\r\n      return 'Retry channel.object.get(). The retried call re-attaches the channel and waits for a fresh objects sync.';\r\n    case 'suspended':\r\n      return 'Retry channel.object.get() once the channel re-attaches. The SDK re-attaches suspended channels automatically when the connection recovers, or call channel.attach() to retry now.';\r\n    default:\r\n      return 'Inspect the cause for the underlying failure. Call channel.attach() to recover the channel, then retry channel.object.get(). Calling channel.object.get() on a failed channel without re-attaching first rejects immediately.';\r\n  }\r\n}\r\n\r\n/**\r\n * Remediation for a `publishAndApply` sync wait failing (RTO20e1), reached via the public mutation\r\n * APIs (`LiveMap.set`/`remove`, `LiveCounter.increment`/`decrement`, batch). The operation was\r\n * published and ACKed before the wait started, so it is persisted server-side and must not be\r\n * retried; only the local optimistic apply failed, and the local object converges on the next\r\n * successful attach and objects sync. State-independent, unlike the `get()` remediation.\r\n */\r\nfunction publishSyncWaitFailureRemediation(): string {\r\n  return 'Do not retry the operation. It was already published and acknowledged by Ably, so retrying would apply it twice. The local object converges automatically on the next successful attach and objects sync. Inspect the cause and channel.errorReason for why the channel left the attached state.';\r\n}\r\n\r\nexport class RealtimeObject {\r\n  gcGracePeriod: number;\r\n\r\n  private _client: BaseClient;\r\n  private _channel: RealtimeChannel;\r\n  private _state: ObjectsState;\r\n  // composition over inheritance since we cannot import class directly into plugin code.\r\n  // instead we obtain a class type from the client\r\n  private _eventEmitterInternal: EventEmitter;\r\n  // related to RTC10, should have a separate EventEmitter for users of the library\r\n  private _eventEmitterPublic: EventEmitter;\r\n  private _objectsPool: ObjectsPool; // RTO3\r\n  private _syncObjectsPool: SyncObjectsPool;\r\n  private _currentSyncId: string | undefined;\r\n  private _currentSyncCursor: string | undefined;\r\n  private _bufferedObjectOperations: ObjectMessage[];\r\n  private _appliedOnAckSerials: Set<string>; // RTO7b\r\n  private _pathObjectSubscriptionRegister: PathObjectSubscriptionRegister;\r\n\r\n  // Used by tests\r\n  static _DEFAULTS = DEFAULTS;\r\n\r\n  constructor(channel: RealtimeChannel) {\r\n    this._channel = channel;\r\n    this._client = channel.client;\r\n    this._state = ObjectsState.initialized;\r\n    this._eventEmitterInternal = new this._client.EventEmitter(this._client.logger);\r\n    this._eventEmitterPublic = new this._client.EventEmitter(this._client.logger);\r\n    this._objectsPool = new ObjectsPool(this);\r\n    this._syncObjectsPool = new SyncObjectsPool(this);\r\n    this._bufferedObjectOperations = [];\r\n    this._appliedOnAckSerials = new Set(); // RTO7b1\r\n    this._pathObjectSubscriptionRegister = new PathObjectSubscriptionRegister(this);\r\n    // use server-provided objectsGCGracePeriod if available, and subscribe to new connectionDetails that can be emitted as part of the RTN24\r\n    this.gcGracePeriod =\r\n      this._channel.connectionManager.connectionDetails?.objectsGCGracePeriod ?? DEFAULTS.gcGracePeriod;\r\n    this._channel.connectionManager.on('connectiondetails', (details: Record<string, any>) => {\r\n      this.gcGracePeriod = details.objectsGCGracePeriod ?? DEFAULTS.gcGracePeriod;\r\n    });\r\n  }\r\n\r\n  /**\r\n   * When called without a type variable, we return a default root type which is based on globally defined interface for Objects feature.\r\n   * A user can provide an explicit type for the this method to explicitly set the type structure on this particular channel.\r\n   * This is useful when working with multiple channels with different underlying data structure.\r\n   */\r\n  async get<T extends Record<string, ObjectsApi.Value>>(): Promise<ObjectsApi.PathObject<ObjectsApi.LiveMap<T>>> {\r\n    this._throwIfMissingChannelMode('object_subscribe');\r\n\r\n    // implicit attach before proceeding\r\n    await this._channel.ensureAttached();\r\n\r\n    // RTO23c - if we're not synced yet, wait for sync sequence to finish before returning root\r\n    if (this._state !== ObjectsState.synced) {\r\n      await this._waitForSyncedOrChannelFailure('the object could not be retrieved', getSyncWaitFailureRemediation); // RTO23c1\r\n    }\r\n\r\n    const pathObject = new DefaultPathObject(this, this._objectsPool.getRoot(), []);\r\n    return pathObject;\r\n  }\r\n\r\n  on(event: ObjectsEvent, callback: ObjectsEventCallback): StatusSubscription {\r\n    // this public API method can be called without specific configuration, so checking for invalid settings is unnecessary.\r\n    this._eventEmitterPublic.on(event, callback);\r\n\r\n    const off = () => {\r\n      this._eventEmitterPublic.off(event, callback);\r\n    };\r\n\r\n    return { off };\r\n  }\r\n\r\n  off(event: ObjectsEvent, callback: ObjectsEventCallback): void {\r\n    // this public API method can be called without specific configuration, so checking for invalid settings is unnecessary.\r\n\r\n    // prevent accidentally calling .off without any arguments on an EventEmitter and removing all callbacks\r\n    if (this._client.Utils.isNil(event) && this._client.Utils.isNil(callback)) {\r\n      return;\r\n    }\r\n\r\n    this._eventEmitterPublic.off(event, callback);\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  getPool(): ObjectsPool {\r\n    return this._objectsPool;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  getChannel(): RealtimeChannel {\r\n    return this._channel;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  getClient(): BaseClient {\r\n    return this._client;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  getPathObjectSubscriptionRegister(): PathObjectSubscriptionRegister {\r\n    return this._pathObjectSubscriptionRegister;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTO5\r\n   *\r\n   * Note on server-initiated resync: if the realtime server needs to force a resync, it is expected\r\n   * to send an ATTACHED message before the new OBJECT_SYNC sequence. However, if an OBJECT_SYNC\r\n   * is received after a previously completed sync without a preceding ATTACHED,\r\n   * we handle it on a best-effort basis: enter the SYNCING state and start buffering OBJECT messages\r\n   * from that point. Since the buffer is cleared at the end of each completed sync sequence, receiving\r\n   * an OBJECT_SYNC while in the SYNCED state means we start with an empty buffer.\r\n   */\r\n  handleObjectSyncMessages(objectMessages: ObjectMessage[], syncChannelSerial: string | null | undefined): void {\r\n    const { syncId, syncCursor } = this._parseSyncChannelSerial(syncChannelSerial); // RTO5a\r\n    const newSyncSequence = this._currentSyncId !== syncId;\r\n    if (newSyncSequence) {\r\n      // RTO5a2 - new sync sequence started\r\n      this._startNewSync(syncId, syncCursor); // RTO5a2a\r\n    }\r\n\r\n    // RTO5a3 - continue current sync sequence\r\n    this._syncObjectsPool.applyObjectSyncMessages(objectMessages); // RTO5f\r\n\r\n    // RTO5a4 - if this is the last (or only) message in a sequence of sync updates, end the sync\r\n    if (!syncCursor) {\r\n      this._endSync(); // RTO5c\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTO8\r\n   */\r\n  handleObjectMessages(objectMessages: ObjectMessage[]): void {\r\n    if (this._state !== ObjectsState.synced) {\r\n      // The client receives object messages in realtime over the channel concurrently with the sync sequence.\r\n      // Some of the incoming object messages may have already been applied to the objects described in\r\n      // the sync sequence, but others may not; therefore we must buffer these messages so that we can apply\r\n      // them to the objects once the sync is complete.\r\n      this._bufferedObjectOperations.push(...objectMessages);\r\n      return;\r\n    }\r\n\r\n    this._applyObjectMessages(objectMessages, ObjectsOperationSource.channel); // RTO8b\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTO4\r\n   */\r\n  onAttached(hasObjects?: boolean): void {\r\n    this._client.Logger.logAction(\r\n      this._client.logger,\r\n      this._client.Logger.LOG_MINOR,\r\n      'RealtimeObject.onAttached()',\r\n      `channel=${this._channel.name}, hasObjects=${hasObjects}`,\r\n    );\r\n\r\n    // Regardless of whether HAS_OBJECTS is set, the client must drop any previously buffered object operations\r\n    // and start a new sync sequence. If HAS_OBJECTS is set, the realtime server will deliver a sync sequence\r\n    // following the ATTACHED, guaranteeing that the objects in that sequence include at least all operations\r\n    // up to the point of attachment.\r\n    // RTO4d\r\n    this._bufferedObjectOperations = [];\r\n    // RTO4c\r\n    this._startNewSync();\r\n\r\n    // RTO4b\r\n    if (!hasObjects) {\r\n      // If no HAS_OBJECTS flag was received on attach, end the sync sequence immediately and treat it as no objects on the channel.\r\n      // Reset the objects pool to its initial state and emit update events so subscribers to the root object are notified of changes.\r\n      this._objectsPool.resetToInitialPool(true); // RTO4b1, RTO4b2\r\n      this._syncObjectsPool.clear(); // RTO4b3\r\n      this._endSync(); // RTO4b4\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * Dispatches channel state changes to the objects data lifecycle handlers: the `ATTACHED`\r\n   * transition is handled per RTO4 (via `onAttached`, which drives the sync lifecycle), and\r\n   * every other state per RTO27.\r\n   * @spec RTO4 - handling of the `ATTACHED` transition\r\n   * @spec RTO27 - manage the stored objects data across non-`ATTACHED` transitions\r\n   */\r\n  actOnChannelState(state: ChannelState, hasObjects?: boolean, reason?: ErrorInfo | null): void {\r\n    switch (state) {\r\n      case 'attached':\r\n        // RTO4 - ATTACHED is handled by onAttached (the sync lifecycle); it is outside RTO27's scope\r\n        this.onAttached(hasObjects);\r\n        break;\r\n\r\n      case 'detached':\r\n      case 'suspended':\r\n      case 'failed':\r\n        // RTO23c1 / RTO20e1 - fail any parked objects-sync waiters (get()/publishAndApply) before the\r\n        // RTO27a data clearing below (drain-then-clear, matching ably-cocoa). The channel's errorReason\r\n        // is not yet assigned when notifyState invokes this handler, so it is passed in as `reason`.\r\n        // Emitted unconditionally; a no-op when no waiter is parked.\r\n        this._eventEmitterInternal.emit(ObjectsInternalEvent.syncWaitFailed, state, reason);\r\n\r\n        if (state !== 'suspended') {\r\n          // RTO27a - the actual current state of Objects data is unknown in DETACHED/FAILED, so clear it\r\n          // without emitting update events (RTO27a1); the objects themselves remain in the pool.\r\n          this._objectsPool.clearObjectsData(false); // RTO27a1\r\n          this._syncObjectsPool.clear(); // RTO27a2\r\n        }\r\n        // RTO27b - SUSPENDED (and every unlisted state: INITIALIZED, ATTACHING, DETACHING) retains the\r\n        // objects data unchanged. For SUSPENDED in particular the connection may still recover, so the\r\n        // retained data remains a valid best-effort local copy.\r\n        break;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTO15\r\n   */\r\n  async publish(objectMessages: ObjectMessage[]): Promise<API.PublishResult> {\r\n    this._channel.throwIfUnpublishableState();\r\n\r\n    const encodedMsgs = objectMessages.map((x) => x.encode());\r\n    const maxMessageSize = this._client.options.maxMessageSize;\r\n    const size = encodedMsgs.reduce((acc, msg) => acc + msg.getMessageSize(), 0);\r\n    if (size > maxMessageSize) {\r\n      throw new this._client.ErrorInfo(\r\n        `Maximum size of object messages that can be published at once exceeded (was ${size} bytes, against a limit of ${maxMessageSize} bytes)`,\r\n        40009,\r\n        400,\r\n      );\r\n    }\r\n\r\n    // RTO15h\r\n    return this._channel.sendState(encodedMsgs);\r\n  }\r\n\r\n  /**\r\n   * Publishes ObjectMessages and applies them locally upon receiving the ACK from the server.\r\n   *\r\n   * @internal\r\n   * @spec RTO20\r\n   */\r\n  async publishAndApply(objectMessages: ObjectMessage[]): Promise<void> {\r\n    // RTO20b\r\n    const publishResult = await this.publish(objectMessages);\r\n\r\n    this._client.Logger.logAction(\r\n      this._client.logger,\r\n      this._client.Logger.LOG_MICRO,\r\n      'RealtimeObject.publishAndApply()',\r\n      `received ACK for ${objectMessages.length} message(s), applying locally; channel=${this._channel.name}`,\r\n    );\r\n\r\n    // RTO20c - check required information is available\r\n    const siteCode = this._channel.connectionManager.connectionDetails?.siteCode;\r\n    // RTO20c1\r\n    if (!siteCode) {\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_ERROR,\r\n        'RealtimeObject.publishAndApply()',\r\n        `operations will not be applied locally: siteCode not available from connectionDetails; channel=${this._channel.name}`,\r\n      );\r\n      return;\r\n    }\r\n    // RTO20c2\r\n    if (!publishResult.serials || publishResult.serials.length !== objectMessages.length) {\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_ERROR,\r\n        'RealtimeObject.publishAndApply()',\r\n        `operations will not be applied locally: PublishResult.serials has unexpected length (expected ${objectMessages.length}, got ${publishResult.serials?.length}); channel=${this._channel.name}`,\r\n      );\r\n      return;\r\n    }\r\n\r\n    // RTO20d\r\n    const syntheticMessages: ObjectMessage[] = [];\r\n    for (let i = 0; i < objectMessages.length; i++) {\r\n      const serial = publishResult.serials[i];\r\n\r\n      // RTO20d1\r\n      if (serial === null) {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MICRO,\r\n          'RealtimeObject.publishAndApply()',\r\n          `operation will not be applied locally: serial is null in PublishResult (index ${i}); channel=${this._channel.name}`,\r\n        );\r\n        continue;\r\n      }\r\n\r\n      // RTO20d2, RTO20d3\r\n      syntheticMessages.push(\r\n        ObjectMessage.fromValues(\r\n          {\r\n            ...objectMessages[i],\r\n            serial, // RTO20d2a\r\n            siteCode, // RTO20d2b\r\n          },\r\n          this._client.Utils,\r\n          this._client.MessageEncoding,\r\n        ),\r\n      );\r\n    }\r\n\r\n    // RTO20d4 - if the synthetic messages list is empty (e.g. every serial was null and skipped per\r\n    // RTO20d1) there is nothing to apply locally, so complete without performing the RTO20e sync wait.\r\n    if (syntheticMessages.length === 0) {\r\n      return;\r\n    }\r\n\r\n    // RTO20e - Wait for sync to complete if not synced\r\n    if (this._state !== ObjectsState.synced) {\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'RealtimeObject.publishAndApply()',\r\n        `waiting for sync to complete before applying ${syntheticMessages.length} message(s); channel=${this._channel.name}`,\r\n      );\r\n\r\n      await this._waitForSyncedOrChannelFailure(\r\n        'the operation could not be applied locally',\r\n        publishSyncWaitFailureRemediation,\r\n      ); // RTO20e1\r\n    }\r\n\r\n    // RTO20f - Apply synthetic messages\r\n    this._client.Logger.logAction(\r\n      this._client.logger,\r\n      this._client.Logger.LOG_MICRO,\r\n      'RealtimeObject.publishAndApply()',\r\n      `applying ${syntheticMessages.length} message(s); channel=${this._channel.name}`,\r\n    );\r\n    this._applyObjectMessages(syntheticMessages, ObjectsOperationSource.local);\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  throwIfInvalidAccessApiConfiguration(): void {\r\n    this._throwIfMissingChannelMode('object_subscribe');\r\n    this._throwIfInChannelState(['detached', 'failed']);\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  throwIfInvalidWriteApiConfiguration(): void {\r\n    this._throwIfMissingChannelMode('object_publish');\r\n    this._throwIfInChannelState(['detached', 'failed', 'suspended']);\r\n    this._throwIfEchoMessagesDisabled();\r\n  }\r\n\r\n  private _startNewSync(syncId?: string, syncCursor?: string): void {\r\n    this._syncObjectsPool.clear();\r\n    this._currentSyncId = syncId;\r\n    this._currentSyncCursor = syncCursor;\r\n    this._stateChange(ObjectsState.syncing);\r\n  }\r\n\r\n  /** @spec RTO5c */\r\n  private _endSync(): void {\r\n    this._applySync();\r\n    // Apply buffered object operations after the sync has been applied.\r\n    // Uses the regular object message application logic.\r\n    this._applyObjectMessages(this._bufferedObjectOperations, ObjectsOperationSource.channel); // RTO5c6\r\n\r\n    this._bufferedObjectOperations = []; // RTO5c5\r\n    this._syncObjectsPool.clear(); // RTO5c4\r\n    this._currentSyncId = undefined; // RTO5c3\r\n    this._currentSyncCursor = undefined; // RTO5c3\r\n\r\n    // RTO5c9 - Clear appliedOnAckSerials\r\n    this._appliedOnAckSerials.clear();\r\n\r\n    this._stateChange(ObjectsState.synced);\r\n  }\r\n\r\n  private _parseSyncChannelSerial(syncChannelSerial: string | null | undefined): {\r\n    syncId: string | undefined;\r\n    syncCursor: string | undefined;\r\n  } {\r\n    let match: RegExpMatchArray | null;\r\n    let syncId: string | undefined = undefined;\r\n    let syncCursor: string | undefined = undefined;\r\n    // RTO5a1 - syncChannelSerial is a two-part identifier: <sequence id>:<cursor value>\r\n    if (syncChannelSerial && (match = syncChannelSerial.match(/^([\\w-]+):(.*)$/))) {\r\n      syncId = match[1];\r\n      syncCursor = match[2];\r\n    }\r\n\r\n    return {\r\n      syncId,\r\n      syncCursor,\r\n    };\r\n  }\r\n\r\n  private _applySync(): void {\r\n    if (this._syncObjectsPool.isEmpty()) {\r\n      return;\r\n    }\r\n\r\n    const receivedObjectIds = new Set<string>();\r\n    const existingObjectUpdates: {\r\n      object: LiveObject;\r\n      update: LiveObjectUpdate | LiveObjectUpdateNoop;\r\n    }[] = [];\r\n\r\n    // RTO5c1\r\n    for (const [objectId, objectMessage] of this._syncObjectsPool.entries()) {\r\n      receivedObjectIds.add(objectId);\r\n      const existingObject = this._objectsPool.get(objectId);\r\n\r\n      // RTO5c1a\r\n      if (existingObject) {\r\n        const update = existingObject.overrideWithObjectState(objectMessage); // RTO5c1a1\r\n        // store updates to call subscription callbacks for all of them once the sync sequence is completed.\r\n        // this will ensure that clients get notified about the changes only once everything has been applied.\r\n        existingObjectUpdates.push({ object: existingObject, update });\r\n        continue;\r\n      }\r\n\r\n      // RTO5c1b\r\n      let newObject: LiveObject;\r\n      if (objectMessage.object?.counter) {\r\n        newObject = LiveCounter.fromObjectState(this, objectMessage); // RTO5c1b1a\r\n      } else if (objectMessage.object?.map) {\r\n        newObject = LiveMap.fromObjectState(this, objectMessage); // RTO5c1b1b\r\n      } else {\r\n        // RTO5c1b1c\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MAJOR,\r\n          'RealtimeObject._applySync()',\r\n          `received unsupported object state message during OBJECT_SYNC, expected 'counter' or 'map' to be present, skipping message; message id: ${objectMessage.id}, channel: ${this._channel.name}`,\r\n        );\r\n        continue;\r\n      }\r\n\r\n      this._objectsPool.set(objectId, newObject); // RTO5c1b1\r\n    }\r\n\r\n    // RTO5c2 - need to remove LiveObject instances from the ObjectsPool for which objectIds were not received during the sync sequence\r\n    this._objectsPool.deleteExtraObjectIds([...receivedObjectIds]);\r\n\r\n    // Rebuild all parent references after sync to ensure all object-to-object references are properly established\r\n    // This is necessary because objects may reference other objects that weren't in the pool when they were initially created\r\n    this._rebuildAllParentReferences();\r\n\r\n    // call subscription callbacks for all updated existing objects.\r\n    existingObjectUpdates.forEach(({ object, update }) => object.notifyUpdated(update));\r\n  }\r\n\r\n  /** @spec RTO9 */\r\n  private _applyObjectMessages(objectMessages: ObjectMessage[], source: ObjectsOperationSource): void {\r\n    for (const objectMessage of objectMessages) {\r\n      if (!objectMessage.operation) {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MAJOR,\r\n          'RealtimeObject._applyObjectMessages()',\r\n          `object operation message is received without 'operation' field, skipping message; message id: ${objectMessage.id}, channel: ${this._channel.name}`,\r\n        );\r\n        continue;\r\n      }\r\n\r\n      const serial = objectMessage.serial;\r\n\r\n      // RTO9a3 - Skip if already applied on ACK\r\n      if (serial && this._appliedOnAckSerials.has(serial)) {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MICRO,\r\n          'RealtimeObject._applyObjectMessages()',\r\n          `skipping message: already applied on ACK; serial=${serial}, channel=${this._channel.name}`,\r\n        );\r\n        this._appliedOnAckSerials.delete(serial);\r\n        continue;\r\n      }\r\n\r\n      const objectOperation = objectMessage.operation;\r\n\r\n      switch (objectOperation.action) {\r\n        case ObjectOperationAction.MAP_CREATE:\r\n        case ObjectOperationAction.COUNTER_CREATE:\r\n        case ObjectOperationAction.MAP_SET:\r\n        case ObjectOperationAction.MAP_REMOVE:\r\n        case ObjectOperationAction.COUNTER_INC:\r\n        case ObjectOperationAction.OBJECT_DELETE:\r\n        case ObjectOperationAction.MAP_CLEAR: {\r\n          // we can receive an op for an object id we don't have yet in the pool. instead of buffering such operations,\r\n          // we can create a zero-value object for the provided object id and apply the operation to that zero-value object.\r\n          // this also means that all objects are capable of applying the corresponding *_CREATE ops on themselves,\r\n          // since they need to be able to eventually initialize themselves from that *_CREATE op.\r\n          // so to simplify operations handling, we always try to create a zero-value object in the pool first,\r\n          // and then we can always apply the operation on the existing object in the pool.\r\n          this._objectsPool.createZeroValueObjectIfNotExists(objectOperation.objectId);\r\n          const applied = this._objectsPool\r\n            .get(objectOperation.objectId)!\r\n            .applyOperation(objectOperation, objectMessage, source); // RTO9a2a3\r\n\r\n          // RTO9a2a4\r\n          if (source === ObjectsOperationSource.local && applied && serial) {\r\n            this._appliedOnAckSerials.add(serial);\r\n          }\r\n          break;\r\n        }\r\n\r\n        default:\r\n          this._client.Logger.logAction(\r\n            this._client.logger,\r\n            this._client.Logger.LOG_MAJOR,\r\n            'RealtimeObject._applyObjectMessages()',\r\n            `received unsupported action in object operation message: ${objectOperation.action}, skipping message; message id: ${objectMessage.id}, channel: ${this._channel.name}`,\r\n          );\r\n      }\r\n    }\r\n  }\r\n\r\n  /** @spec RTO2 */\r\n  private _throwIfMissingChannelMode(expectedMode: 'object_subscribe' | 'object_publish'): void {\r\n    // RTO2a - channel.modes is only populated on channel attachment, so use it only if it is set\r\n    if (this._channel.modes != null && !this._channel.modes.includes(expectedMode)) {\r\n      throw new this._client.ErrorInfo({\r\n        message: `\"${expectedMode}\" channel mode must be set for this operation`,\r\n        code: 40024,\r\n        statusCode: 400,\r\n        remediation: `Include \"${expectedMode}\" in the channel modes: realtime.channels.get(name, { modes: [\"${expectedMode}\", ...] }), or call channel.setOptions({ modes: [...] }) on an existing channel to trigger a reattach. Calling channels.get(name, { modes }) on an existing channel throws. If the mode is still missing after the reattach, your API key lacks the capability corresponding to the mode (\"object-subscribe\" or \"object-publish\") on this channel and the server silently dropped it. If you have the Ably CLI installed, \\`ably auth keys list\\` shows your key's capabilities.`,\r\n      });\r\n    }\r\n    // RTO2b - otherwise as a best effort use user provided channel options\r\n    if (!this._client.Utils.allToLowerCase(this._channel.channelOptions.modes ?? []).includes(expectedMode)) {\r\n      throw new this._client.ErrorInfo({\r\n        message: `\"${expectedMode}\" channel mode must be set for this operation`,\r\n        code: 40024,\r\n        statusCode: 400,\r\n        remediation: `Include \"${expectedMode}\" in the channel modes: realtime.channels.get(name, { modes: [\"${expectedMode}\", ...] }), or call channel.setOptions({ modes: [...] }) on an existing channel to trigger a reattach. Calling channels.get(name, { modes }) on an existing channel throws. If the mode is still missing after the reattach, your API key lacks the capability corresponding to the mode (\"object-subscribe\" or \"object-publish\") on this channel and the server silently dropped it. If you have the Ably CLI installed, \\`ably auth keys list\\` shows your key's capabilities.`,\r\n      });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Waits for the objects sync state to reach SYNCED, rejecting with a 92008 error if the channel\r\n   * first transitions into DETACHED/SUSPENDED/FAILED (signalled by `actOnChannelState` via the\r\n   * internal `syncWaitFailed` event). Shared by `get()` (RTO23c1) and `publishAndApply` (RTO20e1),\r\n   * which differ in the error message's `failureDescription` prefix and in their caller-specific\r\n   * `remediation` (resolved per failure state, since the recovery advice depends on it); the error's\r\n   * code (92008), statusCode (400), and cause (the channel's errorReason) are mandated identically\r\n   * by both spec points, which say nothing about remediation. The cause is the state-change\r\n   * `reason` \u2014 the same error `notifyState` assigns to `RealtimeChannel.errorReason`; on a\r\n   * reason-less transition (e.g. a clean detach) the cause is deliberately absent rather than a\r\n   * stale prior errorReason. Both listeners are removed on either outcome (no leaks).\r\n   */\r\n  private _waitForSyncedOrChannelFailure(\r\n    failureDescription: string,\r\n    remediation: (state: ChannelState) => string,\r\n  ): Promise<void> {\r\n    return new Promise<void>((resolve, reject) => {\r\n      const cleanup = () => {\r\n        this._eventEmitterInternal.off(ObjectsEvent.synced, onSynced);\r\n        this._eventEmitterInternal.off(ObjectsInternalEvent.syncWaitFailed, onChannelFailure);\r\n      };\r\n      const onSynced = () => {\r\n        cleanup();\r\n        resolve();\r\n      };\r\n      const onChannelFailure = (state: ChannelState, reason?: ErrorInfo | null) => {\r\n        cleanup();\r\n        reject(\r\n          new this._client.ErrorInfo({\r\n            message: `${failureDescription} due to the channel entering the ${state} state whilst waiting for objects sync to complete`,\r\n            code: 92008,\r\n            statusCode: 400,\r\n            cause: reason || undefined,\r\n            remediation: remediation(state),\r\n          }),\r\n        );\r\n      };\r\n      this._eventEmitterInternal.once(ObjectsEvent.synced, onSynced);\r\n      this._eventEmitterInternal.once(ObjectsInternalEvent.syncWaitFailed, onChannelFailure);\r\n    });\r\n  }\r\n\r\n  private _stateChange(state: ObjectsState): void {\r\n    if (this._state === state) {\r\n      return;\r\n    }\r\n\r\n    this._state = state;\r\n    const event = StateToEventsMap[state];\r\n    if (!event) {\r\n      return;\r\n    }\r\n\r\n    this._eventEmitterInternal.emit(event);\r\n    this._eventEmitterPublic.emit(event);\r\n  }\r\n\r\n  /**\r\n   * Rebuilds all parent references in the objects pool.\r\n   * This is necessary after sync operations where objects may reference other objects\r\n   * that weren't available when the initial parent references were established.\r\n   */\r\n  private _rebuildAllParentReferences(): void {\r\n    // First, clear all existing parent references\r\n    for (const object of this._objectsPool.getAll()) {\r\n      object.clearParentReferences();\r\n    }\r\n\r\n    // Then, rebuild parent references by examining all objects and their data\r\n    for (const object of this._objectsPool.getAll()) {\r\n      if (object instanceof LiveMap) {\r\n        // For LiveMaps, iterate through their entries and establish parent references\r\n        for (const [key, value] of object.entries()) {\r\n          if (value instanceof LiveObject) {\r\n            value.addParentReference(object, key);\r\n          }\r\n        }\r\n      }\r\n      // Note: LiveCounter doesn't reference other objects, so no special handling needed\r\n    }\r\n  }\r\n\r\n  private _throwIfInChannelState(channelState: ChannelState[]): void {\r\n    if (channelState.includes(this._channel.state)) {\r\n      throw this._client.ErrorInfo.fromValues(this._channel.invalidStateError());\r\n    }\r\n  }\r\n\r\n  private _throwIfEchoMessagesDisabled(): void {\r\n    if (this._channel.client.options.echoMessages === false) {\r\n      throw new this._channel.client.ErrorInfo(\r\n        `\"echoMessages\" client option must be enabled for this operation`,\r\n        40000,\r\n        400,\r\n      );\r\n    }\r\n  }\r\n}\r\n", "import { __livetype } from '../../../ably';\r\nimport { LiveCounter as PublicLiveCounter } from '../../../liveobjects';\r\nimport { LiveObject, LiveObjectData, LiveObjectUpdate, LiveObjectUpdateNoop } from './liveobject';\r\nimport { CounterInc, ObjectData, ObjectMessage, ObjectOperation, ObjectOperationAction } from './objectmessage';\r\nimport { ObjectsOperationSource, RealtimeObject } from './realtimeobject';\r\n\r\nexport interface LiveCounterData extends LiveObjectData {\r\n  data: number; // RTLC3\r\n}\r\n\r\nexport interface LiveCounterUpdate extends LiveObjectUpdate {\r\n  update: { amount: number };\r\n  _type: 'LiveCounterUpdate';\r\n}\r\n\r\n/** @spec RTLC1, RTLC2 */\r\nexport class LiveCounter extends LiveObject<LiveCounterData, LiveCounterUpdate> implements PublicLiveCounter {\r\n  declare readonly [__livetype]: 'LiveCounter'; // type-only, unique symbol to satisfy branded interfaces, no JS emitted\r\n\r\n  /**\r\n   * Returns a {@link LiveCounter} instance with a 0 value.\r\n   *\r\n   * @internal\r\n   * @spec RTLC4\r\n   */\r\n  static zeroValue(realtimeObject: RealtimeObject, objectId: string): LiveCounter {\r\n    return new LiveCounter(realtimeObject, objectId);\r\n  }\r\n\r\n  /**\r\n   * Returns a {@link LiveCounter} instance based on the provided object state.\r\n   * The provided object state must hold a valid counter object data.\r\n   *\r\n   * @internal\r\n   */\r\n  static fromObjectState(realtimeObject: RealtimeObject, objectMessage: ObjectMessage): LiveCounter {\r\n    const obj = new LiveCounter(realtimeObject, objectMessage.object!.objectId);\r\n    obj.overrideWithObjectState(objectMessage);\r\n    return obj;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static createCounterIncMessage(realtimeObject: RealtimeObject, objectId: string, amount: number): ObjectMessage {\r\n    const client = realtimeObject.getClient();\r\n\r\n    if (typeof amount !== 'number' || !Number.isFinite(amount)) {\r\n      throw new client.ErrorInfo('Counter value increment should be a valid number', 40003, 400);\r\n    }\r\n\r\n    const msg = ObjectMessage.fromValues(\r\n      {\r\n        operation: {\r\n          action: ObjectOperationAction.COUNTER_INC, // RTLC12e2\r\n          objectId, // RTLC12e3\r\n          counterInc: { number: amount }, // RTLC12e5\r\n        } as ObjectOperation<ObjectData>,\r\n      },\r\n      client.Utils,\r\n      client.MessageEncoding,\r\n    );\r\n\r\n    return msg;\r\n  }\r\n\r\n  /** @spec RTLC5 */\r\n  value(): number {\r\n    return this._dataRef.data; // RTLC5c\r\n  }\r\n\r\n  /**\r\n   * Send a COUNTER_INC operation to the realtime system to increment a value on this LiveCounter object.\r\n   *\r\n   * The change will be applied locally when the ACK is received from Realtime.\r\n   *\r\n   * @returns A promise which resolves upon receiving the ACK message for the published operation message\r\n   * and applying the operation locally.\r\n   * @spec RTLC12\r\n   */\r\n  async increment(amount: number): Promise<void> {\r\n    const msg = LiveCounter.createCounterIncMessage(this._realtimeObject, this.getObjectId(), amount);\r\n    return this._realtimeObject.publishAndApply([msg]);\r\n  }\r\n\r\n  /**\r\n   * An alias for calling {@link LiveCounter.increment | LiveCounter.increment(-amount)}\r\n   */\r\n  async decrement(amount: number): Promise<void> {\r\n    // do an explicit type safety check here before negating the amount value,\r\n    // so we don't unintentionally change the type sent by a user\r\n    if (typeof amount !== 'number' || !Number.isFinite(amount)) {\r\n      throw new this._client.ErrorInfo('Counter value decrement should be a valid number', 40003, 400);\r\n    }\r\n\r\n    return this.increment(-amount);\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTLC7\r\n   */\r\n  applyOperation(op: ObjectOperation<ObjectData>, msg: ObjectMessage, source: ObjectsOperationSource): boolean {\r\n    if (op.objectId !== this.getObjectId()) {\r\n      throw new this._client.ErrorInfo(\r\n        `Cannot apply object operation with objectId=${op.objectId}, to this LiveCounter with objectId=${this.getObjectId()}`,\r\n        92000,\r\n        400,\r\n      );\r\n    }\r\n\r\n    const opSerial = msg.serial!;\r\n    const opSiteCode = msg.siteCode!;\r\n    if (!this._canApplyOperation(opSerial, opSiteCode)) {\r\n      // _canApplyOperation already logs a warning for malformed serial values; only log\r\n      // the newness-check skip when the serials are well-formed\r\n      if (opSerial && opSiteCode) {\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MICRO,\r\n          'LiveCounter.applyOperation()',\r\n          `skipping ${op.action} op: op serial ${opSerial} <= site serial ${this._siteTimeserials[opSiteCode]}; objectId=${this.getObjectId()}`,\r\n        );\r\n      }\r\n      return false; // RTLC7b\r\n    }\r\n\r\n    // RTLC7c\r\n    if (source === ObjectsOperationSource.channel) {\r\n      // should update stored site serial immediately. doesn't matter if we successfully apply the op,\r\n      // as it's important to mark that the op was processed by the object\r\n      this._siteTimeserials[opSiteCode] = opSerial;\r\n    }\r\n\r\n    if (this.isTombstoned()) {\r\n      // this object is tombstoned so the operation cannot be applied\r\n      return false; // RTLC7e\r\n    }\r\n\r\n    let update: LiveCounterUpdate | LiveObjectUpdateNoop;\r\n    switch (op.action) {\r\n      case ObjectOperationAction.COUNTER_CREATE:\r\n        // RTLC7d1\r\n        update = this._applyCounterCreate(op, msg);\r\n        break;\r\n\r\n      case ObjectOperationAction.COUNTER_INC:\r\n        if (this._client.Utils.isNil(op.counterInc)) {\r\n          this._logNoPayloadWarning(op);\r\n          return false;\r\n        }\r\n        // RTLC7d5\r\n        update = this._applyCounterInc(op.counterInc, msg);\r\n        break;\r\n\r\n      case ObjectOperationAction.OBJECT_DELETE:\r\n        // RTLC7d4\r\n        update = this._applyObjectDelete(msg);\r\n        break;\r\n\r\n      default:\r\n        // RTLC7d3 - log a warning and discard the message without taking any further action\r\n        this._client.Logger.logAction(\r\n          this._client.logger,\r\n          this._client.Logger.LOG_MAJOR,\r\n          'LiveCounter.applyOperation()',\r\n          `object operation message received with unsupported action, skipping message; action=${op.action}, objectId=${this.getObjectId()}`,\r\n        );\r\n        return false;\r\n    }\r\n\r\n    this.notifyUpdated(update); // RTLC7d1a, RTLC7d5a, RTLC7d4a\r\n    return true; // RTLC7d1b, RTLC7d5b, RTLC7d4b\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   * @spec RTLC6\r\n   */\r\n  overrideWithObjectState(objectMessage: ObjectMessage): LiveCounterUpdate | LiveObjectUpdateNoop {\r\n    const objectState = objectMessage.object;\r\n    if (objectState == null) {\r\n      throw new this._client.ErrorInfo(`Missing object state; LiveCounter objectId=${this.getObjectId()}`, 92000, 400);\r\n    }\r\n\r\n    if (objectState.objectId !== this.getObjectId()) {\r\n      throw new this._client.ErrorInfo(\r\n        `Invalid object state: object state objectId=${objectState.objectId}; LiveCounter objectId=${this.getObjectId()}`,\r\n        92000,\r\n        400,\r\n      );\r\n    }\r\n\r\n    if (!this._client.Utils.isNil(objectState.createOp)) {\r\n      // it is expected that create operation can be missing in the object state, so only validate it when it exists\r\n      if (objectState.createOp.objectId !== this.getObjectId()) {\r\n        throw new this._client.ErrorInfo(\r\n          `Invalid object state: object state createOp objectId=${objectState.createOp?.objectId}; LiveCounter objectId=${this.getObjectId()}`,\r\n          92000,\r\n          400,\r\n        );\r\n      }\r\n\r\n      if (objectState.createOp.action !== ObjectOperationAction.COUNTER_CREATE) {\r\n        throw new this._client.ErrorInfo(\r\n          `Invalid object state: object state createOp action=${objectState.createOp?.action}; LiveCounter objectId=${this.getObjectId()}`,\r\n          92000,\r\n          400,\r\n        );\r\n      }\r\n    }\r\n\r\n    // object's site serials are still updated even if it is tombstoned, so always use the site serials received from the operation.\r\n    // should default to empty map if site serials do not exist on the object state, so that any future operation may be applied to this object.\r\n    this._siteTimeserials = objectState.siteTimeserials ?? {}; // RTLC6a\r\n\r\n    if (this.isTombstoned()) {\r\n      // this object is tombstoned. this is a terminal state which can't be overridden. skip the rest of object state message processing\r\n      return { noop: true };\r\n    }\r\n\r\n    if (objectState.tombstone) {\r\n      // tombstone this object and ignore the data from the object state message\r\n      return this.tombstone(objectMessage);\r\n    }\r\n\r\n    // otherwise override data for this object with data from the object state\r\n    const previousDataRef = this._dataRef;\r\n    this._createOperationIsMerged = false; // RTLC6b\r\n    this._dataRef = { data: objectState.counter?.count ?? 0 }; // RTLC6c\r\n    // RTLC6d\r\n    if (!this._client.Utils.isNil(objectState.createOp)) {\r\n      this._mergeInitialDataFromCreateOperation(objectState.createOp, objectMessage);\r\n    }\r\n\r\n    // update will contain the diff between previous value and new value from object state\r\n    const update = this._updateFromDataDiff(previousDataRef, this._dataRef);\r\n    // RTLC14c - _updateFromDataDiff collapses a zero-delta diff (unchanged counter data) to a noop.\r\n    // pass it straight through without stamping the object message, mirroring the terminal noop\r\n    // return above (RTLC6e).\r\n    if (this._isNoopUpdate(update)) {\r\n      return update;\r\n    }\r\n    update.objectMessage = objectMessage;\r\n\r\n    return update;\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  onGCInterval(): void {\r\n    // nothing to GC for a counter object\r\n    return;\r\n  }\r\n\r\n  /** @spec RTLC4 */\r\n  protected _getZeroValueData(): LiveCounterData {\r\n    return { data: 0 };\r\n  }\r\n\r\n  protected _updateFromDataDiff(\r\n    prevDataRef: LiveCounterData,\r\n    newDataRef: LiveCounterData,\r\n  ): LiveCounterUpdate | LiveObjectUpdateNoop {\r\n    const counterDiff = newDataRef.data - prevDataRef.data;\r\n    // RTLC14c - as an exception to RTLC14b: if newData equals previousData (the computed delta is 0)\r\n    // the counter data did not change, so instead of returning an update return a LiveCounterUpdate\r\n    // object with noop set to true (RTLO4b4b), as in RTLC9h. This exception must not be applied when\r\n    // the diff is computed for a tombstone per RTLO4e5; LiveObject.tombstone re-synthesizes a\r\n    // non-noop update via _createNoChangeUpdate() so the RTLO4b4c3c listener teardown still fires.\r\n    if (counterDiff === 0) {\r\n      return { noop: true };\r\n    }\r\n    return { update: { amount: counterDiff }, _type: 'LiveCounterUpdate' };\r\n  }\r\n\r\n  protected _createNoChangeUpdate(): LiveCounterUpdate {\r\n    // RTLO4e5 tombstone carve-out (RTLC14c) - a zero-delta no-change update for an already-zero counter\r\n    return { update: { amount: 0 }, _type: 'LiveCounterUpdate' };\r\n  }\r\n\r\n  protected _mergeInitialDataFromCreateOperation(\r\n    objectOperation: ObjectOperation<ObjectData>,\r\n    msg: ObjectMessage,\r\n  ): LiveCounterUpdate | LiveObjectUpdateNoop {\r\n    // RTLC16 - resolve counterCreate from either the direct property or the one from which counterCreateWithObjectId was derived\r\n    const counterCreate = objectOperation.counterCreate ?? objectOperation.counterCreateWithObjectId?._derivedFrom;\r\n    const count = counterCreate?.count;\r\n\r\n    // RTLC16b - the create op counts as merged even when it carries no count; RTLC8's\r\n    // duplicate-create skip relies on this flag being set once the op has been processed\r\n    this._createOperationIsMerged = true;\r\n\r\n    if (this._client.Utils.isNil(count)) {\r\n      // RTLC16d - a create operation without an initial count is a noop (nothing to add per RTLC16a)\r\n      return { noop: true };\r\n    }\r\n\r\n    // note that it is intentional to SUM the incoming count from the create op.\r\n    // if we got here, it means that current counter instance is missing the initial value in its data reference,\r\n    // which we're going to add now.\r\n    this._dataRef.data += count; // RTLC16a\r\n\r\n    // RTLC16c\r\n    return {\r\n      update: { amount: count },\r\n      objectMessage: msg,\r\n      _type: 'LiveCounterUpdate',\r\n    };\r\n  }\r\n\r\n  private _logNoPayloadWarning(op: ObjectOperation<ObjectData>): void {\r\n    // a message with a missing operation payload is malformed; log a warning and discard\r\n    // it without aborting the processing of sibling operations in the same ProtocolMessage\r\n    this._client.Logger.logAction(\r\n      this._client.logger,\r\n      this._client.Logger.LOG_MAJOR,\r\n      'LiveCounter.applyOperation()',\r\n      `no payload found for ${op.action} op, skipping message; objectId=${this.getObjectId()}`,\r\n    );\r\n  }\r\n\r\n  private _applyCounterCreate(\r\n    op: ObjectOperation<ObjectData>,\r\n    msg: ObjectMessage,\r\n  ): LiveCounterUpdate | LiveObjectUpdateNoop {\r\n    if (this._createOperationIsMerged) {\r\n      // There can't be two different create operation for the same object id, because the object id\r\n      // fully encodes that operation. This means we can safely ignore any new incoming create operations\r\n      // if we already merged it once.\r\n      this._client.Logger.logAction(\r\n        this._client.logger,\r\n        this._client.Logger.LOG_MICRO,\r\n        'LiveCounter._applyCounterCreate()',\r\n        `skipping applying COUNTER_CREATE op on a counter instance as it was already applied before; objectId=${this.getObjectId()}`,\r\n      );\r\n      return { noop: true };\r\n    }\r\n\r\n    return this._mergeInitialDataFromCreateOperation(op, msg);\r\n  }\r\n\r\n  /** @spec RTLC9, RTLC9a2 */\r\n  private _applyCounterInc(op: CounterInc, msg: ObjectMessage): LiveCounterUpdate | LiveObjectUpdateNoop {\r\n    if (this._client.Utils.isNil(op.number)) {\r\n      // RTLC9h - a COUNTER_INC without a number is a noop\r\n      return { noop: true };\r\n    }\r\n\r\n    this._dataRef.data += op.number; // RTLC9f\r\n    return {\r\n      update: { amount: op.number }, // RTLC9g\r\n      objectMessage: msg,\r\n      _type: 'LiveCounterUpdate',\r\n    };\r\n  }\r\n}\r\n", "import { __livetype } from '../../../ably';\r\nimport { LiveMap as PublicLiveMap, Primitive, Value } from '../../../liveobjects';\r\nimport { LiveCounterValueType } from './livecountervaluetype';\r\nimport { LiveMap, LiveMapObjectData, ObjectIdObjectData } from './livemap';\r\nimport { ObjectId } from './objectid';\r\nimport {\r\n  encodePartialObjectOperationForWire,\r\n  MapCreate,\r\n  ObjectData,\r\n  ObjectMessage,\r\n  ObjectOperation,\r\n  ObjectOperationAction,\r\n  ObjectsMapEntry,\r\n  ObjectsMapSemantics,\r\n  primitiveToObjectData,\r\n} from './objectmessage';\r\nimport { RealtimeObject } from './realtimeobject';\r\n\r\n/**\r\n * A value type class that serves as a simple container for LiveMap data.\r\n * Contains sufficient information for the client to produce a MAP_CREATE operation\r\n * for the LiveMap object.\r\n *\r\n * Properties of this class are immutable after construction and the instance\r\n * will be frozen to prevent mutation.\r\n *\r\n * Note: We do not deep freeze or deep copy the entries data for the following reasons:\r\n * 1. It adds substantial complexity, especially for handling Buffer/ArrayBuffer values\r\n * 2. Cross-platform buffer copying would require reimplementing BufferUtils logic\r\n *    to handle browser vs Node.js environments and check availability of Buffer/ArrayBuffer\r\n * 3. The protection isn't critical - if users mutate the data after creating the value type,\r\n *    nothing breaks since we create separate live objects each time the value type is used\r\n * 4. This behavior should be documented and it's the user's responsibility to understand\r\n *    how they mutate their data when working with value type classes\r\n */\r\nexport class LiveMapValueType<T extends Record<string, Value> = Record<string, Value>> implements PublicLiveMap<T> {\r\n  declare readonly [__livetype]: 'LiveMap'; // type-only, unique symbol to satisfy branded interfaces, no JS emitted\r\n  private readonly _livetype = 'LiveMap'; // use a runtime property to provide a reliable cross-bundle type identification instead of `instanceof` operator\r\n  private readonly _entries: T | undefined;\r\n\r\n  private constructor(entries: T | undefined) {\r\n    this._entries = entries;\r\n    Object.freeze(this);\r\n  }\r\n\r\n  static create<T extends Record<string, Value>>(\r\n    initialEntries?: T,\r\n  ): PublicLiveMap<T extends Record<string, Value> ? T : {}> {\r\n    // We can't directly import the ErrorInfo class from the core library into the plugin (as this would bloat the plugin size),\r\n    // and, since we're in a user-facing static method, we can't expect a user to pass a client library instance, as this would make the API ugly.\r\n    // Since we can't use ErrorInfo here, we won't do any validation at this step; instead, validation will happen in the mutation methods\r\n    // when we try to create this object.\r\n\r\n    return new LiveMapValueType(initialEntries);\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static instanceof(value: unknown): value is LiveMapValueType {\r\n    return typeof value === 'object' && value !== null && (value as LiveMapValueType)._livetype === 'LiveMap';\r\n  }\r\n\r\n  /**\r\n   * @internal\r\n   */\r\n  static async createMapCreateMessage(\r\n    realtimeObject: RealtimeObject,\r\n    value: LiveMapValueType,\r\n  ): Promise<{ mapCreateMsg: ObjectMessage; nestedObjectsCreateMsgs: ObjectMessage[] }> {\r\n    const client = realtimeObject.getClient();\r\n    const entries = value._entries;\r\n\r\n    if (entries !== undefined && (entries === null || typeof entries !== 'object')) {\r\n      throw new client.ErrorInfo('Map entries should be a key-value object', 40003, 400);\r\n    }\r\n\r\n    Object.entries(entries ?? {}).forEach(([key, value]) => LiveMap.validateKeyValue(realtimeObject, key, value));\r\n\r\n    const { mapCreate, nestedObjectsCreateMsgs } = await LiveMapValueType._getMapCreate(realtimeObject, entries); // RTO11f14\r\n    const { mapCreate: encodedMapCreate } = encodePartialObjectOperationForWire(\r\n      { mapCreate },\r\n      client,\r\n      client.Utils.Format.json,\r\n    ); // RTO11f15a\r\n    const initialValueJSONString = JSON.stringify(encodedMapCreate); // RTO11f15b\r\n    const nonce = await ObjectId.generateNonce(client); // RTO11f6\r\n    const msTimestamp = await client.getTimestamp(true); // RTO11f7\r\n\r\n    // RTO11f8\r\n    const objectId = ObjectId.fromInitialValue(\r\n      client.Platform,\r\n      'map',\r\n      initialValueJSONString,\r\n      nonce,\r\n      msTimestamp,\r\n    ).toString();\r\n\r\n    const mapCreateMsg = ObjectMessage.fromValues(\r\n      {\r\n        operation: {\r\n          action: ObjectOperationAction.MAP_CREATE, // RTO11f9\r\n          objectId, // RTO11f10\r\n          mapCreateWithObjectId: {\r\n            nonce, // RTO11f16\r\n            initialValue: initialValueJSONString, // RTO11f17\r\n            // RTO11f18 - retain the source MapCreate for local use (size calculation and apply-on-ACK)\r\n            _derivedFrom: mapCreate,\r\n          },\r\n        } as ObjectOperation<ObjectData>,\r\n      },\r\n      client.Utils,\r\n      client.MessageEncoding,\r\n    );\r\n\r\n    return {\r\n      mapCreateMsg,\r\n      nestedObjectsCreateMsgs,\r\n    };\r\n  }\r\n\r\n  private static async _getMapCreate(\r\n    realtimeObject: RealtimeObject,\r\n    entries?: Record<string, Value>,\r\n  ): Promise<{\r\n    mapCreate: MapCreate<ObjectData>;\r\n    nestedObjectsCreateMsgs: ObjectMessage[];\r\n  }> {\r\n    const mapEntries: Record<string, ObjectsMapEntry<ObjectData>> = {}; // RTO11f14b - empty map by default\r\n    const nestedObjectsCreateMsgs: ObjectMessage[] = [];\r\n\r\n    // RTO11f14c\r\n    for (const [key, value] of Object.entries(entries ?? {})) {\r\n      let objectData: LiveMapObjectData;\r\n\r\n      if (LiveMapValueType.instanceof(value)) {\r\n        const { mapCreateMsg, nestedObjectsCreateMsgs: childNestedObjs } =\r\n          await LiveMapValueType.createMapCreateMessage(realtimeObject, value);\r\n        nestedObjectsCreateMsgs.push(...childNestedObjs, mapCreateMsg);\r\n        const typedObjectData: ObjectIdObjectData = { objectId: mapCreateMsg.operation?.objectId! };\r\n        objectData = typedObjectData;\r\n      } else if (LiveCounterValueType.instanceof(value)) {\r\n        const counterCreateMsg = await LiveCounterValueType.createCounterCreateMessage(realtimeObject, value);\r\n        nestedObjectsCreateMsgs.push(counterCreateMsg);\r\n        const typedObjectData: ObjectIdObjectData = { objectId: counterCreateMsg.operation?.objectId! };\r\n        objectData = typedObjectData;\r\n      } else {\r\n        // RTO11f14c1b, RTO11f14c1c, RTO11f14c1d, RTO11f14c1e, RTO11f14c1f - Handle primitive values\r\n        objectData = primitiveToObjectData(value as Primitive, realtimeObject.getClient());\r\n      }\r\n\r\n      // RTO11f14c1, RTO11f14c2\r\n      mapEntries[key] = {\r\n        data: objectData,\r\n      };\r\n    }\r\n\r\n    const mapCreate: MapCreate<ObjectData> = {\r\n      semantics: ObjectsMapSemantics.LWW, // RTO11f14a\r\n      entries: mapEntries, // RTO11f14b, RTO11f14c\r\n    };\r\n\r\n    return {\r\n      mapCreate,\r\n      nestedObjectsCreateMsgs,\r\n    };\r\n  }\r\n}\r\n", "import type RestChannel from 'common/lib/client/restchannel';\r\nimport type * as Utils from 'common/lib/util/utils';\r\nimport type { FlattenUnion } from 'common/types/utils';\r\nimport type {\r\n  ObjectsMapSemantics,\r\n  RestLiveMap,\r\n  RestLiveObject,\r\n  RestObject as PublicRestObject,\r\n  RestObjectData,\r\n  RestObjectGenerateIdResult,\r\n  RestObjectGetCompactParams,\r\n  RestObjectGetCompactResult,\r\n  RestObjectGetFullParams,\r\n  RestObjectGetFullResult,\r\n  RestObjectGetParams,\r\n  RestObjectOperation,\r\n  RestObjectOperationCounterCreateBody,\r\n  RestObjectOperationMapCreateBody,\r\n  RestObjectPublishResult,\r\n} from '../../../liveobjects';\r\nimport { ObjectId } from './objectid';\r\nimport {\r\n  CounterCreate,\r\n  CounterCreateWithObjectId,\r\n  CounterInc,\r\n  decodeWireObjectData,\r\n  encodeMapSemantics,\r\n  encodePartialObjectOperationForWire,\r\n  MapCreate,\r\n  MapCreateWithObjectId,\r\n  MapRemove,\r\n  MapSet,\r\n  ObjectData,\r\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n  ObjectOperation,\r\n  WireObjectData,\r\n} from './objectmessage';\r\n\r\nenum WireObjectsMapSemantics {\r\n  LWW = 'LWW',\r\n}\r\n\r\nconst mapSemanticsWireToPublic: Record<WireObjectsMapSemantics, ObjectsMapSemantics> = {\r\n  [WireObjectsMapSemantics.LWW]: 'lww',\r\n};\r\n\r\n/** Wire format for a full GET response: either a live object or a typed leaf value. */\r\ntype WireRestObjectGetFullResult = WireRestLiveObject | WireObjectData;\r\n\r\ntype WireRestLiveObject = WireRestLiveMap | WireRestLiveCounter | WireAnyRestLiveObject;\r\n\r\ninterface WireRestLiveMap {\r\n  objectId: string;\r\n  map: {\r\n    semantics: WireObjectsMapSemantics;\r\n    entries: Record<string, { data: WireObjectData | WireRestLiveObject }>;\r\n  };\r\n}\r\n\r\ninterface WireRestLiveCounter {\r\n  objectId: string;\r\n  counter: {\r\n    data: {\r\n      number: number;\r\n    };\r\n  };\r\n}\r\n\r\ntype WireAnyRestLiveObject = {\r\n  objectId: string;\r\n};\r\n\r\n/**\r\n * Wire format for a REST publish operation, based on {@link ObjectOperation} from the realtime protocol.\r\n * The `action` field is omitted as the server infers it from the operation-specific field.\r\n * Includes additional REST-specific fields such as `id` and `path`.\r\n */\r\ninterface WireRestObjectOperation {\r\n  id?: string;\r\n  path?: string;\r\n  objectId?: string;\r\n  mapCreate?: MapCreate<WireObjectData>;\r\n  mapSet?: MapSet<WireObjectData>;\r\n  mapRemove?: MapRemove;\r\n  counterCreate?: CounterCreate;\r\n  counterInc?: CounterInc;\r\n  mapCreateWithObjectId?: Omit<MapCreateWithObjectId<WireObjectData>, '_derivedFrom'>;\r\n  counterCreateWithObjectId?: Omit<CounterCreateWithObjectId, '_derivedFrom'>;\r\n}\r\n\r\n/**\r\n * Flattened view of {@link RestObjectOperation} with all possible fields as optional.\r\n * Derived from the public union type so it stays in sync automatically.\r\n */\r\ntype AnyRestObjectOperation = FlattenUnion<RestObjectOperation>;\r\n\r\nexport class RestObject implements PublicRestObject {\r\n  constructor(private _channel: RestChannel) {}\r\n\r\n  async get(params?: RestObjectGetCompactParams): Promise<RestObjectGetCompactResult>;\r\n  async get(params: RestObjectGetFullParams): Promise<RestObjectGetFullResult>;\r\n  async get(params?: RestObjectGetParams): Promise<RestObjectGetCompactResult | RestObjectGetFullResult> {\r\n    const client = this._channel.client;\r\n    const format = client.options.useBinaryProtocol ? client.Utils.Format.msgpack : client.Utils.Format.json;\r\n    const headers = client.Defaults.defaultGetHeaders(client.options);\r\n\r\n    client.Utils.mixin(headers, client.options.headers);\r\n\r\n    const { unpacked, body } = await client.rest.Resource.get<RestObjectGetCompactResult | WireRestObjectGetFullResult>(\r\n      client,\r\n      this._basePath(params?.objectId),\r\n      headers,\r\n      params ?? {},\r\n      null,\r\n      true,\r\n    );\r\n\r\n    const decoded = unpacked\r\n      ? body!\r\n      : client.Utils.decodeBody<RestObjectGetCompactResult | WireRestObjectGetFullResult>(\r\n          body,\r\n          client._MsgPack,\r\n          format,\r\n        );\r\n\r\n    const compact = params?.compact ?? true;\r\n    if (compact) {\r\n      // Compact mode: return as-is. Values are JSON-like; bytes appear as base64 strings\r\n      // (JSON protocol) or Buffer/ArrayBuffer (binary protocol). We cannot deterministically\r\n      // decode values since we can't tell string vs JSON-encoded string.\r\n      return decoded as RestObjectGetCompactResult;\r\n    }\r\n\r\n    // Full mode: response is a live object (map/counter) or a typed leaf ObjectData.\r\n    // Decode wire values using objectmessage decoding.\r\n    return this._decodeFullResponseNode(decoded as WireRestObjectGetFullResult, format);\r\n  }\r\n\r\n  async publish(op: RestObjectOperation | RestObjectOperation[]): Promise<RestObjectPublishResult> {\r\n    const client = this._channel.client;\r\n    const format = client.options.useBinaryProtocol ? client.Utils.Format.msgpack : client.Utils.Format.json;\r\n    const headers = client.Defaults.defaultPostHeaders(client.options, { format });\r\n\r\n    const wireOps = Array.isArray(op)\r\n      ? op.map((o) => this._constructWireOperations(o, format))\r\n      : [this._constructWireOperations(op, format)];\r\n\r\n    client.Utils.mixin(headers, client.options.headers);\r\n\r\n    const requestBody = client.Utils.encodeBody(wireOps, client._MsgPack, format);\r\n\r\n    const { unpacked, body } = await client.rest.Resource.post<RestObjectPublishResult>(\r\n      client,\r\n      this._basePath(),\r\n      requestBody,\r\n      headers,\r\n      {},\r\n      null,\r\n      true,\r\n    );\r\n\r\n    return unpacked ? body! : client.Utils.decodeBody(body, client._MsgPack, format);\r\n  }\r\n\r\n  async generateObjectId(\r\n    createBody: RestObjectOperationMapCreateBody | RestObjectOperationCounterCreateBody,\r\n  ): Promise<RestObjectGenerateIdResult> {\r\n    const client = this._channel.client;\r\n    // operations for initialValue string are always encoded as JSON format\r\n    const format = client.Utils.Format.json;\r\n\r\n    let objectType: 'map' | 'counter';\r\n    let initialValueJSONString: string;\r\n\r\n    if ('mapCreate' in createBody && createBody.mapCreate) {\r\n      objectType = 'map';\r\n      const mapCreate: MapCreate<ObjectData> = {\r\n        ...createBody.mapCreate,\r\n        semantics: encodeMapSemantics(createBody.mapCreate.semantics, client),\r\n      };\r\n      const { mapCreate: encodedMapCreate } = encodePartialObjectOperationForWire({ mapCreate }, client, format);\r\n      initialValueJSONString = JSON.stringify(encodedMapCreate);\r\n    } else if ('counterCreate' in createBody && createBody.counterCreate) {\r\n      objectType = 'counter';\r\n      const { counterCreate: encodedCounterCreate } = encodePartialObjectOperationForWire(createBody, client, format);\r\n      initialValueJSONString = JSON.stringify(encodedCounterCreate);\r\n    } else {\r\n      throw new client.ErrorInfo('generateObjectId requires a mapCreate or counterCreate property', 40003, 400);\r\n    }\r\n\r\n    const nonce = await ObjectId.generateNonce(client);\r\n    const msTimestamp = await client.getTimestamp(true);\r\n\r\n    const objectId = ObjectId.fromInitialValue(\r\n      client.Platform,\r\n      objectType,\r\n      initialValueJSONString,\r\n      nonce,\r\n      msTimestamp,\r\n    ).toString();\r\n\r\n    return {\r\n      objectId,\r\n      nonce,\r\n      initialValue: initialValueJSONString,\r\n    };\r\n  }\r\n\r\n  private _basePath(objectId?: string): string {\r\n    return (\r\n      this._channel.client.rest.channelMixin.basePath(this._channel) +\r\n      '/object' +\r\n      (objectId ? '/' + encodeURIComponent(objectId) : '')\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Decodes a node in the full GET response object graph.\r\n   * Called for both the top-level response body and recursively for nested map entry data.\r\n   * The wire node is either a live object (map/counter) or a typed leaf value {@link WireObjectData}.\r\n   *\r\n   * Known object types are decoded based on the current contract (maps have entries decoded,\r\n   * ObjectData has bytes/json decoded). Unrecognized object types or fields are passed through as-is.\r\n   */\r\n  private _decodeFullResponseNode(\r\n    wire: WireRestLiveObject | WireObjectData,\r\n    format: Utils.Format,\r\n  ): RestLiveObject | RestObjectData {\r\n    if ('map' in wire) {\r\n      return this._decodeWireRestLiveMap(wire, format);\r\n    }\r\n\r\n    if ('counter' in wire) {\r\n      // live counter - no decoding needed\r\n      return wire;\r\n    }\r\n\r\n    // typed leaf ObjectData (string, number, boolean, bytes, json, objectId) or unknown live object type.\r\n    // decodeWireObjectData handles all ObjectData fields and passes through unrecognized shapes.\r\n    return decodeWireObjectData(wire, this._channel.client, format);\r\n  }\r\n\r\n  private _decodeWireRestLiveMap(wire: WireRestLiveMap, format: Utils.Format): RestLiveMap {\r\n    const entries: RestLiveMap['map']['entries'] = {};\r\n\r\n    for (const [key, entry] of Object.entries(wire.map.entries ?? {})) {\r\n      entries[key] = {\r\n        data: this._decodeFullResponseNode(entry.data, format),\r\n      };\r\n    }\r\n\r\n    // construct the public RestLiveMap object, and include any unrecognized fields as-is\r\n    const liveMap: RestLiveMap = {\r\n      ...wire,\r\n      objectId: wire.objectId,\r\n      map: {\r\n        ...wire.map,\r\n        semantics: mapSemanticsWireToPublic[wire.map.semantics] ?? 'unknown',\r\n        entries: entries,\r\n      },\r\n    };\r\n    return liveMap;\r\n  }\r\n\r\n  private _constructWireOperations(op: AnyRestObjectOperation, format: Utils.Format): WireRestObjectOperation {\r\n    const { id, path, mapCreate, ...rest } = op;\r\n\r\n    // Build the operation fields for encoding. If mapCreate is present, convert semantics\r\n    // from public string to internal enum before passing to the encoding pipeline.\r\n    const operationFields: Partial<ObjectOperation<ObjectData>> = mapCreate\r\n      ? {\r\n          ...rest,\r\n          mapCreate: { ...mapCreate, semantics: encodeMapSemantics(mapCreate.semantics, this._channel.client) },\r\n        }\r\n      : rest;\r\n\r\n    // Encode ObjectData values (json stringification, bytes encoding) via ObjectMessage pipeline.\r\n    const encoded = encodePartialObjectOperationForWire(operationFields, this._channel.client, format);\r\n\r\n    const result: WireRestObjectOperation = { ...encoded };\r\n    if (id != null) result.id = id;\r\n    if (path != null) result.path = path;\r\n    return result;\r\n  }\r\n}\r\n", "import { LiveCounterValueType } from './livecountervaluetype';\r\nimport { LiveMapValueType } from './livemapvaluetype';\r\nimport { ObjectId } from './objectid';\r\nimport { ObjectMessage, WireObjectMessage } from './objectmessage';\r\nimport { RealtimeObject } from './realtimeobject';\r\nimport { RestObject } from './restobject';\r\n\r\nexport {\r\n  LiveCounterValueType as LiveCounter,\r\n  LiveMapValueType as LiveMap,\r\n  ObjectId,\r\n  ObjectMessage,\r\n  RealtimeObject,\r\n  RestObject,\r\n  WireObjectMessage,\r\n};\r\n\r\n/**\r\n * The named LiveObjects plugin object export to be passed to the Ably client.\r\n */\r\nexport const LiveObjects = {\r\n  LiveCounter: LiveCounterValueType,\r\n  LiveMap: LiveMapValueType,\r\n  ObjectId,\r\n  ObjectMessage,\r\n  RealtimeObject,\r\n  RestObject,\r\n  WireObjectMessage,\r\n};\r\n"],
  "mappings": "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",
  "names": ["result", "_a", "_a", "value"]
}
