@twilio/conversations 3.0.0-rc.1 → 3.0.0-rc.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +7 -3
  3. package/builds/browser.js +1643 -1410
  4. package/builds/browser.js.map +1 -1
  5. package/builds/lib.d.ts +270 -182
  6. package/builds/lib.js +1643 -1410
  7. package/builds/lib.js.map +1 -1
  8. package/builds/twilio-conversations.js +3719 -4034
  9. package/builds/twilio-conversations.min.js +1 -16
  10. package/dist/aggregated-delivery-receipt.js.map +1 -1
  11. package/dist/client.js +53 -35
  12. package/dist/client.js.map +1 -1
  13. package/dist/command-executor.js.map +1 -1
  14. package/dist/configuration.js.map +1 -1
  15. package/dist/conversation.js +405 -376
  16. package/dist/conversation.js.map +1 -1
  17. package/dist/data/conversations.js +10 -11
  18. package/dist/data/conversations.js.map +1 -1
  19. package/dist/data/messages.js +9 -9
  20. package/dist/data/messages.js.map +1 -1
  21. package/dist/data/participants.js +19 -10
  22. package/dist/data/participants.js.map +1 -1
  23. package/dist/data/users.js +2 -2
  24. package/dist/data/users.js.map +1 -1
  25. package/dist/detailed-delivery-receipt.js.map +1 -1
  26. package/dist/index.js +6 -4
  27. package/dist/index.js.map +1 -1
  28. package/dist/interfaces/attributes.js.map +1 -1
  29. package/dist/interfaces/notification-types.js.map +1 -1
  30. package/dist/logger.js +2 -4
  31. package/dist/logger.js.map +1 -1
  32. package/dist/media.js.map +1 -1
  33. package/dist/message-builder.js.map +1 -1
  34. package/dist/message.js +16 -12
  35. package/dist/message.js.map +1 -1
  36. package/dist/node_modules/tslib/tslib.es6.js +1 -1
  37. package/dist/node_modules/tslib/tslib.es6.js.map +1 -1
  38. package/dist/packages/conversations/package.json.js +1 -1
  39. package/dist/participant.js +2 -2
  40. package/dist/participant.js.map +1 -1
  41. package/dist/push-notification.js.map +1 -1
  42. package/dist/rest-paginator.js.map +1 -1
  43. package/dist/services/network.js.map +1 -1
  44. package/dist/services/typing-indicator.js +1 -1
  45. package/dist/services/typing-indicator.js.map +1 -1
  46. package/dist/unsent-message.js.map +1 -1
  47. package/dist/user.js +1 -1
  48. package/dist/user.js.map +1 -1
  49. package/dist/util/deferred.js.map +1 -1
  50. package/dist/util/index.js.map +1 -1
  51. package/docs/assets/js/search.js +1 -1
  52. package/docs/classes/CancellablePromise.html +3213 -0
  53. package/docs/classes/Client.html +4 -10
  54. package/docs/classes/Conversation.html +80 -51
  55. package/docs/classes/Media.html +2 -2
  56. package/docs/classes/Message.html +6 -6
  57. package/docs/classes/MessageBuilder.html +2 -2
  58. package/docs/classes/PushNotification.html +1 -1
  59. package/docs/classes/UnsentMessage.html +2 -2
  60. package/docs/index.html +20 -25
  61. package/docs/interfaces/ConversationState.html +2 -2
  62. package/docs/interfaces/ConversationUpdatedEventArgs.html +3001 -0
  63. package/docs/interfaces/PushNotificationData.html +48 -0
  64. package/docs/modules.html +19 -24
  65. package/package.json +21 -19
@@ -131,6 +131,7 @@ This software includes platform.js under the following license.
131
131
  Object.defineProperty(exports, '__esModule', { value: true });
132
132
 
133
133
  var tslib_es6 = require('./node_modules/tslib/tslib.es6.js');
134
+ require('isomorphic-form-data');
134
135
  var logger = require('./logger.js');
135
136
  var participants = require('./data/participants.js');
136
137
  var participant = require('./participant.js');
@@ -146,7 +147,9 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
146
147
 
147
148
  var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
148
149
 
149
- const log = logger.Logger.scope("Conversation");
150
+ /**
151
+ * Map of the fields that will be processed with update messages.
152
+ */
150
153
  const fieldMappings = {
151
154
  lastMessage: "lastMessage",
152
155
  attributes: "attributes",
@@ -162,255 +165,150 @@ const fieldMappings = {
162
165
  state: "state",
163
166
  bindings: "bindings",
164
167
  };
165
- function parseTime(timeString) {
166
- try {
167
- return new Date(timeString);
168
- }
169
- catch (e) {
170
- return null;
171
- }
172
- }
173
168
  /**
174
- * A conversation represents communication between multiple Conversations clients
169
+ * A conversation represents communication between multiple Conversations
170
+ * clients.
175
171
  */
176
172
  class Conversation extends replayEventEmitter.ReplayEventEmitter {
177
173
  /**
174
+ * @param descriptor Conversation descriptor.
175
+ * @param sid Conversation SID.
176
+ * @param links Conversation links for REST requests.
177
+ * @param configuration Client configuration.
178
+ * @param services Conversation services.
178
179
  * @internal
179
180
  */
180
181
  constructor(descriptor, sid, links, configuration, services) {
181
- var _a;
182
+ var _a, _b;
182
183
  super();
183
184
  this.sid = sid;
184
- this.links = links;
185
- this.configuration = configuration;
186
- this.services = services;
187
- const attributes = descriptor.attributes || {};
188
- const createdBy = descriptor.createdBy;
189
- const dateCreated = parseTime(descriptor.dateCreated);
190
- const dateUpdated = parseTime(descriptor.dateUpdated);
191
- const friendlyName = descriptor.friendlyName || null;
192
- const lastReadMessageIndex = Number.isInteger(descriptor.lastConsumedMessageIndex)
193
- ? descriptor.lastConsumedMessageIndex
194
- : null;
195
- const uniqueName = descriptor.uniqueName || null;
196
- try {
197
- JSON.stringify(attributes);
198
- }
199
- catch (e) {
200
- throw new Error("Attributes must be a valid JSON object.");
201
- }
202
- this.entityName = descriptor.channel;
203
- this.channelState = {
204
- uniqueName,
185
+ this._links = links;
186
+ this._configuration = configuration;
187
+ this._services = services;
188
+ this._entityName = descriptor.channel;
189
+ this._internalState = {
190
+ uniqueName: descriptor.uniqueName || null,
205
191
  status: "notParticipating",
206
- attributes,
207
- createdBy,
208
- dateCreated,
209
- dateUpdated,
210
- friendlyName,
211
- lastReadMessageIndex,
212
- bindings: (_a = descriptor.bindings) !== null && _a !== void 0 ? _a : {},
192
+ attributes: (_a = descriptor.attributes) !== null && _a !== void 0 ? _a : {},
193
+ createdBy: descriptor.createdBy,
194
+ dateCreated: index.parseTime(descriptor.dateCreated),
195
+ dateUpdated: index.parseTime(descriptor.dateUpdated),
196
+ friendlyName: descriptor.friendlyName || null,
197
+ lastReadMessageIndex: Number.isInteger(descriptor.lastConsumedMessageIndex)
198
+ ? descriptor.lastConsumedMessageIndex
199
+ : null,
200
+ bindings: (_b = descriptor.bindings) !== null && _b !== void 0 ? _b : {},
213
201
  };
214
202
  if (descriptor.notificationLevel) {
215
- this.channelState.notificationLevel = descriptor.notificationLevel;
203
+ this._internalState.notificationLevel = descriptor.notificationLevel;
216
204
  }
217
205
  const participantsLinks = {
218
- participants: this.links.participants,
206
+ participants: this._links.participants,
219
207
  };
220
- this.participants = new Map();
221
- this.participantsEntity = new participants.Participants(this, this.participants, participantsLinks, this.configuration, this.services);
222
- this.participantsEntity.on("participantJoined", (participant) => this.emit("participantJoined", participant));
223
- this.participantsEntity.on("participantLeft", (participant) => this.emit("participantLeft", participant));
224
- this.participantsEntity.on("participantUpdated", (args) => this.emit("participantUpdated", args));
225
- this.messagesEntity = new messages.Messages(this, configuration, services);
226
- this.messagesEntity.on("messageAdded", (message) => this._onMessageAdded(message));
227
- this.messagesEntity.on("messageUpdated", (args) => this.emit("messageUpdated", args));
228
- this.messagesEntity.on("messageRemoved", (message) => this.emit("messageRemoved", message));
208
+ this._participants = new Map();
209
+ this._participantsEntity = new participants.Participants(this, this._participants, participantsLinks, this._configuration, this._services);
210
+ this._participantsEntity.on("participantJoined", (participant) => this.emit("participantJoined", participant));
211
+ this._participantsEntity.on("participantLeft", (participant) => this.emit("participantLeft", participant));
212
+ this._participantsEntity.on("participantUpdated", (args) => this.emit("participantUpdated", args));
213
+ this._messagesEntity = new messages.Messages(this, configuration, services);
214
+ this._messagesEntity.on("messageAdded", (message) => this._onMessageAdded(message));
215
+ this._messagesEntity.on("messageUpdated", (args) => this.emit("messageUpdated", args));
216
+ this._messagesEntity.on("messageRemoved", (message) => this.emit("messageRemoved", message));
229
217
  }
230
218
  /**
231
219
  * Unique name of the conversation.
232
220
  */
233
221
  get uniqueName() {
234
- return this.channelState.uniqueName;
222
+ return this._internalState.uniqueName;
235
223
  }
236
224
  /**
237
225
  * Status of the conversation.
238
226
  */
239
227
  get status() {
240
- return this.channelState.status;
228
+ return this._internalState.status;
241
229
  }
242
230
  /**
243
231
  * Name of the conversation.
244
232
  */
245
233
  get friendlyName() {
246
- return this.channelState.friendlyName;
234
+ return this._internalState.friendlyName;
247
235
  }
248
236
  /**
249
237
  * Date this conversation was last updated on.
250
238
  */
251
239
  get dateUpdated() {
252
- return this.channelState.dateUpdated;
240
+ return this._internalState.dateUpdated;
253
241
  }
254
242
  /**
255
243
  * Date this conversation was created on.
256
244
  */
257
245
  get dateCreated() {
258
- return this.channelState.dateCreated;
246
+ return this._internalState.dateCreated;
259
247
  }
260
248
  /**
261
249
  * Identity of the user that created this conversation.
262
250
  */
263
251
  get createdBy() {
264
252
  var _a;
265
- return (_a = this.channelState.createdBy) !== null && _a !== void 0 ? _a : "";
253
+ return (_a = this._internalState.createdBy) !== null && _a !== void 0 ? _a : "";
266
254
  }
267
255
  /**
268
256
  * Custom attributes of the conversation.
269
257
  */
270
258
  get attributes() {
271
- return this.channelState.attributes;
259
+ return this._internalState.attributes;
272
260
  }
273
261
  /**
274
262
  * Index of the last message the user has read in this conversation.
275
263
  */
276
264
  get lastReadMessageIndex() {
277
- return this.channelState.lastReadMessageIndex;
265
+ return this._internalState.lastReadMessageIndex;
278
266
  }
279
267
  /**
280
268
  * Last message sent to this conversation.
281
269
  */
282
270
  get lastMessage() {
283
271
  var _a;
284
- return (_a = this.channelState.lastMessage) !== null && _a !== void 0 ? _a : undefined;
272
+ return (_a = this._internalState.lastMessage) !== null && _a !== void 0 ? _a : undefined;
285
273
  }
286
274
  /**
287
275
  * User notification level for this conversation.
288
276
  */
289
277
  get notificationLevel() {
290
278
  var _a;
291
- return (_a = this.channelState.notificationLevel) !== null && _a !== void 0 ? _a : "default";
279
+ return (_a = this._internalState.notificationLevel) !== null && _a !== void 0 ? _a : "default";
292
280
  }
281
+ /**
282
+ * Conversation bindings. Undocumented feature (for now).
283
+ * @internal
284
+ */
293
285
  get bindings() {
294
- return this.channelState.bindings;
286
+ return this._internalState.bindings;
295
287
  }
296
288
  /**
297
289
  * Current conversation limits.
298
290
  */
299
291
  get limits() {
300
- return this.configuration.limits;
292
+ return this._configuration.limits;
301
293
  }
302
294
  /**
303
295
  * State of the conversation.
304
296
  */
305
297
  get state() {
306
- return this.channelState.state;
307
- }
308
- /**
309
- * Load and subscribe to this conversation and do not subscribe to its participants and messages.
310
- * This or _subscribeStreams will need to be called before any events on conversation will fire.
311
- * @internal
312
- */
313
- _subscribe() {
314
- var _a;
315
- return (this.entityPromise =
316
- (_a = this.entityPromise) !== null && _a !== void 0 ? _a : this.services.syncClient
317
- .document({ id: this.entityName, mode: "open_existing" })
318
- .then((entity) => {
319
- this.entity = entity;
320
- this.entity.on("updated", (args) => {
321
- this._update(args.data);
322
- });
323
- this.entity.on("removed", () => this.emit("removed", this));
324
- this._update(this.entity.data);
325
- return entity;
326
- })
327
- .catch((err) => {
328
- this.entity = null;
329
- this.entityPromise = null;
330
- if (this.services.syncClient.connectionState != "disconnected") {
331
- log.error("Failed to get conversation object", err);
332
- }
333
- log.debug("ERROR: Failed to get conversation object", err);
334
- throw err;
335
- }));
298
+ return this._internalState.state;
336
299
  }
337
300
  /**
338
- * Load the attributes of this conversation and instantiate its participants and messages.
339
- * This or _subscribe will need to be called before any events on the conversation will fire.
340
- * This will need to be called before any events on participants or messages will fire
301
+ * Source of the conversation update.
341
302
  * @internal
342
303
  */
343
- async _subscribeStreams() {
344
- var _a, _b, _c;
345
- try {
346
- await this._subscribe();
347
- log.trace("_subscribeStreams, this.entity.data=", (_a = this.entity) === null || _a === void 0 ? void 0 : _a.data);
348
- const messagesObjectName = ((_b = this.entity) === null || _b === void 0 ? void 0 : _b.data)
349
- .messages;
350
- const rosterObjectName = ((_c = this.entity) === null || _c === void 0 ? void 0 : _c.data)
351
- .roster;
352
- await Promise.all([
353
- this.messagesEntity.subscribe(messagesObjectName),
354
- this.participantsEntity.subscribe(rosterObjectName),
355
- ]);
356
- }
357
- catch (err) {
358
- if (this.services.syncClient.connectionState !== "disconnected") {
359
- log.error("Failed to subscribe on conversation objects", this.sid, err);
360
- }
361
- log.debug("ERROR: Failed to subscribe on conversation objects", this.sid, err);
362
- throw err;
363
- }
304
+ get _statusSource() {
305
+ return this._dataSource;
364
306
  }
365
307
  /**
366
- * Stop listening for and firing events on this conversation.
367
- * @internal
308
+ * Preprocess the update object.
309
+ * @param update The update object received from Sync.
310
+ * @param conversationSid The SID of the conversation in question.
368
311
  */
369
- async _unsubscribe() {
370
- if (this.entity) {
371
- await this.entity.close();
372
- this.entity = null;
373
- this.entityPromise = null;
374
- }
375
- return Promise.all([
376
- this.participantsEntity.unsubscribe(),
377
- this.messagesEntity.unsubscribe(),
378
- ]);
379
- }
380
- /**
381
- * Set conversation status.
382
- * @internal
383
- */
384
- _setStatus(status, source) {
385
- this.statusSource = source;
386
- if (this.channelState.status === status) {
387
- return;
388
- }
389
- this.channelState.status = status;
390
- if (status === "joined") {
391
- this._subscribeStreams().catch((err) => {
392
- log.debug("ERROR while setting conversation status " + status, err);
393
- if (this.services.syncClient.connectionState !== "disconnected") {
394
- throw err;
395
- }
396
- });
397
- }
398
- else if (this.entityPromise) {
399
- this._unsubscribe().catch((err) => {
400
- log.debug("ERROR while setting conversation status " + status, err);
401
- if (this.services.syncClient.connectionState !== "disconnected") {
402
- throw err;
403
- }
404
- });
405
- }
406
- }
407
- /**
408
- * Get the source of the conversation update.
409
- * @internal
410
- */
411
- _statusSource() {
412
- return this.statusSource;
413
- }
414
312
  static preprocessUpdate(update, conversationSid) {
415
313
  try {
416
314
  if (typeof update.attributes === "string") {
@@ -421,27 +319,23 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
421
319
  }
422
320
  }
423
321
  catch (e) {
424
- log.warn("Retrieved malformed attributes from the server for conversation: " +
322
+ Conversation._logger.warn("Retrieved malformed attributes from the server for conversation: " +
425
323
  conversationSid);
426
324
  update.attributes = {};
427
325
  }
428
326
  try {
429
- if (update.dateCreated) {
430
- update.dateCreated = new Date(update.dateCreated);
431
- }
327
+ update.dateCreated && (update.dateCreated = new Date(update.dateCreated));
432
328
  }
433
329
  catch (e) {
434
- log.warn("Retrieved malformed dateCreated from the server for conversation: " +
330
+ Conversation._logger.warn("Retrieved malformed dateCreated from the server for conversation: " +
435
331
  conversationSid);
436
332
  delete update.dateCreated;
437
333
  }
438
334
  try {
439
- if (update.dateUpdated) {
440
- update.dateUpdated = new Date(update.dateUpdated);
441
- }
335
+ update.dateUpdated && (update.dateUpdated = new Date(update.dateUpdated));
442
336
  }
443
337
  catch (e) {
444
- log.warn("Retrieved malformed dateUpdated from the server for conversation: " +
338
+ Conversation._logger.warn("Retrieved malformed dateUpdated from the server for conversation: " +
445
339
  conversationSid);
446
340
  delete update.dateUpdated;
447
341
  }
@@ -451,158 +345,44 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
451
345
  }
452
346
  }
453
347
  catch (e) {
454
- log.warn("Retrieved malformed lastMessage.timestamp from the server for conversation: " +
348
+ Conversation._logger.warn("Retrieved malformed lastMessage.timestamp from the server for conversation: " +
455
349
  conversationSid);
456
350
  delete update.lastMessage.timestamp;
457
351
  }
458
352
  }
459
- /**
460
- * Update the local conversation object with new values.
461
- * @internal
462
- */
463
- _update(update) {
464
- var _a, _b, _c, _d, _e;
465
- log.trace("_update", update);
466
- Conversation.preprocessUpdate(update, this.sid);
467
- const updateReasons = new Set();
468
- for (const key of Object.keys(update)) {
469
- const localKey = fieldMappings[key];
470
- if (!localKey) {
471
- continue;
472
- }
473
- switch (localKey) {
474
- case fieldMappings.status:
475
- if (!update.status ||
476
- update.status === "unknown" ||
477
- this.channelState.status === update.status) {
478
- break;
479
- }
480
- this.channelState.status = update.status;
481
- updateReasons.add(localKey);
482
- break;
483
- case fieldMappings.attributes:
484
- if (isEqual__default['default'](this.channelState.attributes, update.attributes)) {
485
- break;
486
- }
487
- this.channelState.attributes = update.attributes;
488
- updateReasons.add(localKey);
489
- break;
490
- case fieldMappings.lastConsumedMessageIndex:
491
- if (update.lastConsumedMessageIndex === undefined ||
492
- update.lastConsumedMessageIndex ===
493
- this.channelState.lastReadMessageIndex) {
494
- break;
495
- }
496
- this.channelState.lastReadMessageIndex =
497
- update.lastConsumedMessageIndex;
498
- updateReasons.add("lastReadMessageIndex");
499
- break;
500
- case fieldMappings.lastMessage:
501
- if (this.channelState.lastMessage && !update.lastMessage) {
502
- delete this.channelState.lastMessage;
503
- updateReasons.add(localKey);
504
- break;
505
- }
506
- this.channelState.lastMessage = this.channelState.lastMessage || {};
507
- if (((_a = update.lastMessage) === null || _a === void 0 ? void 0 : _a.index) !== undefined &&
508
- update.lastMessage.index !== this.channelState.lastMessage.index) {
509
- this.channelState.lastMessage.index = update.lastMessage.index;
510
- updateReasons.add(localKey);
511
- }
512
- if (((_b = update.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp) !== undefined &&
513
- ((_d = (_c = this.channelState.lastMessage) === null || _c === void 0 ? void 0 : _c.dateCreated) === null || _d === void 0 ? void 0 : _d.getTime()) !==
514
- update.lastMessage.timestamp.getTime()) {
515
- this.channelState.lastMessage.dateCreated =
516
- update.lastMessage.timestamp;
517
- updateReasons.add(localKey);
518
- }
519
- if (isEqual__default['default'](this.channelState.lastMessage, {})) {
520
- delete this.channelState.lastMessage;
521
- }
522
- break;
523
- case fieldMappings.state:
524
- const state = update.state || undefined;
525
- if (state !== undefined) {
526
- state.dateUpdated = new Date(state.dateUpdated);
527
- }
528
- if (isEqual__default['default'](this.channelState.state, state)) {
529
- break;
530
- }
531
- this.channelState.state = state;
532
- updateReasons.add(localKey);
533
- break;
534
- case fieldMappings.bindings:
535
- if (isEqual__default['default'](this.channelState.bindings, update.bindings)) {
536
- break;
537
- }
538
- this.channelState.bindings = update.bindings;
539
- updateReasons.add(localKey);
540
- break;
541
- default:
542
- const isDate = update[key] instanceof Date;
543
- const keysMatchAsDates = isDate &&
544
- ((_e = this.channelState[localKey]) === null || _e === void 0 ? void 0 : _e.getTime()) === update[key].getTime();
545
- const keysMatchAsNonDates = !isDate && this[localKey] === update[key];
546
- if (keysMatchAsDates || keysMatchAsNonDates) {
547
- break;
548
- }
549
- this.channelState[localKey] = update[key];
550
- updateReasons.add(localKey);
551
- }
552
- }
553
- if (updateReasons.size > 0) {
554
- this.emit("updated", {
555
- conversation: this,
556
- updateReasons: [...updateReasons],
557
- });
558
- }
559
- }
560
- /**
561
- * @internal
562
- */
563
- _onMessageAdded(message) {
564
- for (const participant of this.participants.values()) {
565
- if (participant.identity === message.author) {
566
- participant._endTyping();
567
- break;
568
- }
569
- }
570
- this.emit("messageAdded", message);
571
- }
572
- async _setLastReadMessageIndex(index) {
573
- const result = await this.services.commandExecutor.mutateResource("post", `${this.configuration.links.myConversations}/${this.sid}`, {
574
- last_read_message_index: index,
575
- });
576
- return result.unread_messages_count;
577
- }
578
353
  /**
579
354
  * Add a participant to the conversation by its identity.
580
355
  * @param identity Identity of the Client to add.
581
356
  * @param attributes Attributes to be attached to the participant.
357
+ * @returns The added participant.
582
358
  */
583
359
  async add(identity, attributes) {
584
- return this.participantsEntity.add(identity, attributes !== null && attributes !== void 0 ? attributes : {});
360
+ return this._participantsEntity.add(identity, attributes !== null && attributes !== void 0 ? attributes : {});
585
361
  }
586
362
  /**
587
363
  * Add a non-chat participant to the conversation.
588
364
  * @param proxyAddress Proxy (Twilio) address of the participant.
589
365
  * @param address User address of the participant.
590
366
  * @param attributes Attributes to be attached to the participant.
591
- * @param bindingOptions Options for adding email participants - name and CC/To level.
367
+ * @param bindingOptions Options for adding email participants - name and
368
+ * CC/To level.
369
+ * @returns The added participant.
592
370
  */
593
371
  async addNonChatParticipant(proxyAddress, address, attributes = {}, bindingOptions = {}) {
594
- return this.participantsEntity.addNonChatParticipant(proxyAddress, address, attributes !== null && attributes !== void 0 ? attributes : {}, bindingOptions !== null && bindingOptions !== void 0 ? bindingOptions : {});
372
+ return this._participantsEntity.addNonChatParticipant(proxyAddress, address, attributes !== null && attributes !== void 0 ? attributes : {}, bindingOptions !== null && bindingOptions !== void 0 ? bindingOptions : {});
595
373
  }
596
374
  /**
597
- * Advance the conversation's last read message index to the current read horizon.
598
- * Rejects if the user is not a participant of the conversation.
599
- * Last read message index is updated only if the new index value is higher than the previous.
375
+ * Advance the conversation's last read message index to the current read
376
+ * horizon. Rejects if the user is not a participant of the conversation. Last
377
+ * read message index is updated only if the new index value is higher than
378
+ * the previous.
600
379
  * @param index Message index to advance to.
601
380
  * @return Resulting unread messages count in the conversation.
602
381
  */
603
382
  async advanceLastReadMessageIndex(index) {
383
+ var _a;
604
384
  await this._subscribeStreams();
605
- if (index < (this.lastReadMessageIndex || 0)) {
385
+ if (index < ((_a = this.lastReadMessageIndex) !== null && _a !== void 0 ? _a : 0)) {
606
386
  return await this._setLastReadMessageIndex(this.lastReadMessageIndex);
607
387
  }
608
388
  return await this._setLastReadMessageIndex(index);
@@ -611,7 +391,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
611
391
  * Delete the conversation and unsubscribe from its events.
612
392
  */
613
393
  async delete() {
614
- await this.services.commandExecutor.mutateResource("delete", this.links.self);
394
+ await this._services.commandExecutor.mutateResource("delete", this._links.self);
615
395
  return this;
616
396
  }
617
397
  /**
@@ -623,39 +403,43 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
623
403
  }
624
404
  /**
625
405
  * Returns messages from the conversation using the paginator interface.
626
- * @param pageSize Number of messages to return in a single chunk. Default is 30.
627
- * @param anchor Index of the newest message to fetch. Default is from the end.
628
- * @param direction Query direction. By default it queries backwards
629
- * from newer to older. The `"forward"` value will query in the opposite direction.
406
+ * @param pageSize Number of messages to return in a single chunk. Default is
407
+ * 30.
408
+ * @param anchor Index of the newest message to fetch. Default is from the
409
+ * end.
410
+ * @param direction Query direction. By default, it queries backwards
411
+ * from newer to older. The `"forward"` value will query in the opposite
412
+ * direction.
630
413
  * @return A page of messages.
631
414
  */
632
415
  async getMessages(pageSize, anchor, direction) {
633
416
  await this._subscribeStreams();
634
- return this.messagesEntity.getMessages(pageSize, anchor, direction);
417
+ return this._messagesEntity.getMessages(pageSize, anchor, direction);
635
418
  }
636
419
  /**
637
420
  * Get a list of all the participants who are joined to this conversation.
638
421
  */
639
422
  async getParticipants() {
640
423
  await this._subscribeStreams();
641
- return this.participantsEntity.getParticipants();
424
+ return this._participantsEntity.getParticipants();
642
425
  }
643
426
  /**
644
427
  * Get conversation participants count.
645
428
  *
646
- * This method is semi-realtime. This means that this data will be eventually correct,
647
- * but will also be possibly incorrect for a few seconds. The Conversations system does not
648
- * provide real time events for counter values changes.
429
+ * This method is semi-realtime. This means that this data will be eventually
430
+ * correct, but will also be possibly incorrect for a few seconds. The
431
+ * Conversations system does not provide real time events for counter values
432
+ * changes.
649
433
  *
650
- * This is useful for any UI badges, but it is not recommended to build any core application
651
- * logic based on these counters being accurate in real time.
434
+ * This is useful for any UI badges, but it is not recommended to build any
435
+ * core application logic based on these counters being accurate in real time.
652
436
  */
653
437
  async getParticipantsCount() {
654
438
  var _a;
655
- const url = new index.UriBuilder(this.configuration.links.conversations)
439
+ const url = new index.UriBuilder(this._configuration.links.conversations)
656
440
  .path(this.sid)
657
441
  .build();
658
- const response = await this.services.network.get(url);
442
+ const response = await this._services.network.get(url);
659
443
  return (_a = response.body.participants_count) !== null && _a !== void 0 ? _a : 0;
660
444
  }
661
445
  /**
@@ -663,53 +447,55 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
663
447
  * @param participantSid Participant SID.
664
448
  */
665
449
  async getParticipantBySid(participantSid) {
666
- return this.participantsEntity.getParticipantBySid(participantSid);
450
+ return this._participantsEntity.getParticipantBySid(participantSid);
667
451
  }
668
452
  /**
669
453
  * Get a participant by its identity.
670
454
  * @param identity Participant identity.
671
455
  */
672
456
  async getParticipantByIdentity(identity = "") {
673
- return this.participantsEntity.getParticipantByIdentity(identity !== null && identity !== void 0 ? identity : "");
457
+ return this._participantsEntity.getParticipantByIdentity(identity !== null && identity !== void 0 ? identity : "");
674
458
  }
675
459
  /**
676
460
  * Get the total message count in the conversation.
677
461
  *
678
- * This method is semi-realtime. This means that this data will be eventually correct,
679
- * but will also be possibly incorrect for a few seconds. The Conversations system does not
680
- * provide real time events for counter values changes.
462
+ * This method is semi-realtime. This means that this data will be eventually
463
+ * correct, but will also be possibly incorrect for a few seconds. The
464
+ * Conversations system does not provide real time events for counter values
465
+ * changes.
681
466
  *
682
- * This is useful for any UI badges, but it is not recommended to build any core application
683
- * logic based on these counters being accurate in real time.
467
+ * This is useful for any UI badges, but it is not recommended to build any
468
+ * core application logic based on these counters being accurate in real time.
684
469
  */
685
470
  async getMessagesCount() {
686
471
  var _a;
687
- const url = new index.UriBuilder(this.configuration.links.conversations)
472
+ const url = new index.UriBuilder(this._configuration.links.conversations)
688
473
  .path(this.sid)
689
474
  .build();
690
- const response = await this.services.network.get(url);
475
+ const response = await this._services.network.get(url);
691
476
  return (_a = response.body.messages_count) !== null && _a !== void 0 ? _a : 0;
692
477
  }
693
478
  /**
694
- * Get unread messages count for the user if they are a participant of this conversation.
695
- * Rejects if the user is not a participant of the conversation.
479
+ * Get unread messages count for the user if they are a participant of this
480
+ * conversation. Rejects if the user is not a participant of the conversation.
696
481
  *
697
482
  * Use this method to obtain the number of unread messages together with
698
483
  * {@link Conversation.updateLastReadMessageIndex} instead of relying on the
699
484
  * message indices which may have gaps. See {@link Message.index} for details.
700
485
  *
701
- * This method is semi-realtime. This means that this data will be eventually correct,
702
- * but will also be possibly incorrect for a few seconds. The Conversations system does not
703
- * provide real time events for counter values changes.
486
+ * This method is semi-realtime. This means that this data will be eventually
487
+ * correct, but will also be possibly incorrect for a few seconds. The
488
+ * Conversations system does not provide real time events for counter values
489
+ * changes.
704
490
  *
705
- * This is useful for any UI badges, but it is not recommended to build any core application
706
- * logic based on these counters being accurate in real time.
491
+ * This is useful for any UI badges, but it is not recommended to build any
492
+ * core application logic based on these counters being accurate in real time.
707
493
  */
708
494
  async getUnreadMessagesCount() {
709
- const url = new index.UriBuilder(this.configuration.links.myConversations)
495
+ const url = new index.UriBuilder(this._configuration.links.myConversations)
710
496
  .path(this.sid)
711
497
  .build();
712
- const response = await this.services.network.get(url);
498
+ const response = await this._services.network.get(url);
713
499
  if (response.body.conversation_sid !== this.sid) {
714
500
  throw new Error("Conversation was not found in the user conversations list");
715
501
  }
@@ -723,8 +509,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
723
509
  * Join the conversation and subscribe to its events.
724
510
  */
725
511
  async join() {
726
- await this.services.commandExecutor.mutateResource("post", this.links.participants, {
727
- identity: this.configuration.userIdentity,
512
+ await this._services.commandExecutor.mutateResource("post", this._links.participants, {
513
+ identity: this._configuration.userIdentity,
728
514
  });
729
515
  return this;
730
516
  }
@@ -732,8 +518,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
732
518
  * Leave the conversation.
733
519
  */
734
520
  async leave() {
735
- if (this.channelState.status === "joined") {
736
- await this.services.commandExecutor.mutateResource("delete", `${this.links.participants}/${this.configuration.userIdentity}`);
521
+ if (this._internalState.status === "joined") {
522
+ await this._services.commandExecutor.mutateResource("delete", `${this._links.participants}/${this._configuration.userIdentity}`);
737
523
  }
738
524
  return this;
739
525
  }
@@ -742,15 +528,14 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
742
528
  * argument, it will assume that the string is an identity or SID.
743
529
  * @param participant Identity, SID or the participant object to remove.
744
530
  */
745
- /* eslint-disable @typescript-eslint/ban-ts-comment */
746
- // @ts-ignore TODO: fix validateTypesAsync typing
747
531
  async removeParticipant(participant) {
748
- await this.participantsEntity.remove(typeof participant === "string" ? participant : participant.sid);
532
+ await this._participantsEntity.remove(typeof participant === "string" ? participant : participant.sid);
749
533
  }
750
534
  /**
751
535
  * Send a message to the conversation.
752
536
  * @param message Message body for the text message,
753
- * `FormData` or {@link SendMediaOptions} for media content. Sending FormData is supported only with the browser engine.
537
+ * `FormData` or {@link SendMediaOptions} for media content. Sending FormData
538
+ * is supported only with the browser engine.
754
539
  * @param messageAttributes Attributes for the message.
755
540
  * @param emailOptions Email options for the message.
756
541
  * @return Index of the new message.
@@ -758,22 +543,23 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
758
543
  async sendMessage(message, messageAttributes, emailOptions) {
759
544
  var _a, _b;
760
545
  if (typeof message === "string" || message === null) {
761
- const response = await this.messagesEntity.send(message, messageAttributes, emailOptions);
546
+ const response = await this._messagesEntity.send(message, messageAttributes, emailOptions);
762
547
  return (_a = index.parseToNumber(response.index)) !== null && _a !== void 0 ? _a : 0;
763
548
  }
764
- const response = await this.messagesEntity.sendMedia(message, messageAttributes, emailOptions);
549
+ const response = await this._messagesEntity.sendMedia(message, messageAttributes, emailOptions);
765
550
  return (_b = index.parseToNumber(response.index)) !== null && _b !== void 0 ? _b : 0;
766
551
  }
767
552
  /**
768
553
  * New interface to prepare for sending a message.
769
- * Use instead of `sendMessage`.
554
+ * Use this instead of {@link Message.sendMessage}.
770
555
  * @return A MessageBuilder to help set all message sending options.
771
556
  */
772
557
  prepareMessage() {
773
- return new messageBuilder.MessageBuilder(this.limits, this.messagesEntity);
558
+ return new messageBuilder.MessageBuilder(this.limits, this._messagesEntity);
774
559
  }
775
560
  /**
776
- * Set last read message index of the conversation to the index of the last known message.
561
+ * Set last read message index of the conversation to the index of the last
562
+ * known message.
777
563
  * @return Resulting unread messages count in the conversation.
778
564
  */
779
565
  async setAllMessagesRead() {
@@ -782,7 +568,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
782
568
  if (messagesPage.items.length > 0) {
783
569
  return this.advanceLastReadMessageIndex(messagesPage.items[0].index);
784
570
  }
785
- return Promise.resolve(0);
571
+ return 0;
786
572
  }
787
573
  /**
788
574
  * Set all messages in the conversation unread.
@@ -797,23 +583,25 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
797
583
  * @param notificationLevel New user notification level.
798
584
  */
799
585
  async setUserNotificationLevel(notificationLevel) {
800
- await this.services.commandExecutor.mutateResource("post", `${this.configuration.links.myConversations}/${this.sid}`, {
586
+ await this._services.commandExecutor.mutateResource("post", `${this._configuration.links.myConversations}/${this.sid}`, {
801
587
  notification_level: notificationLevel,
802
588
  });
803
589
  }
804
590
  /**
805
- * Send a notification to the server indicating that this client is currently typing in this conversation.
806
- * Typing ended notification is sent after a while automatically, but by calling this method again you ensure that typing ended is not received.
591
+ * Send a notification to the server indicating that this client is currently
592
+ * typing in this conversation. Typing ended notification is sent after a
593
+ * while automatically, but by calling this method again you ensure that
594
+ * typing ended is not received.
807
595
  */
808
596
  typing() {
809
- return this.services.typingIndicator.send(this.sid);
597
+ return this._services.typingIndicator.send(this.sid);
810
598
  }
811
599
  /**
812
600
  * Update the attributes of the conversation.
813
601
  * @param attributes New attributes.
814
602
  */
815
603
  async updateAttributes(attributes) {
816
- await this.services.commandExecutor.mutateResource("post", this.links.self, {
604
+ await this._services.commandExecutor.mutateResource("post", this._links.self, {
817
605
  attributes: attributes !== undefined ? JSON.stringify(attributes) : undefined,
818
606
  });
819
607
  return this;
@@ -823,15 +611,15 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
823
611
  * @param friendlyName New friendly name.
824
612
  */
825
613
  async updateFriendlyName(friendlyName) {
826
- if (this.channelState.friendlyName !== friendlyName) {
827
- await this.services.commandExecutor.mutateResource("post", this.links.self, { friendly_name: friendlyName });
614
+ if (this._internalState.friendlyName !== friendlyName) {
615
+ await this._services.commandExecutor.mutateResource("post", this._links.self, { friendly_name: friendlyName });
828
616
  }
829
617
  return this;
830
618
  }
831
619
  /**
832
620
  * Set the last read message index to the current read horizon.
833
- * @param index Message index to set as last read.
834
- * If null is provided, then the behavior is identical to {@link Conversation.setAllMessagesUnread}.
621
+ * @param index Message index to set as last read. If null is provided, then
622
+ * the behavior is identical to {@link Conversation.setAllMessagesUnread}.
835
623
  * @returns Resulting unread messages count in the conversation.
836
624
  */
837
625
  async updateLastReadMessageIndex(index) {
@@ -840,25 +628,251 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
840
628
  }
841
629
  /**
842
630
  * Update the unique name of the conversation.
843
- * @param uniqueName New unique name for the conversation. Setting unique name to null removes it.
631
+ * @param uniqueName New unique name for the conversation. Setting unique name
632
+ * to null removes it.
844
633
  */
845
634
  async updateUniqueName(uniqueName) {
846
- if (this.channelState.uniqueName !== uniqueName) {
847
- if (!uniqueName) {
848
- uniqueName = "";
849
- }
850
- await this.services.commandExecutor.mutateResource("post", this.links.self, {
635
+ if (this._internalState.uniqueName !== uniqueName) {
636
+ uniqueName || (uniqueName = "");
637
+ await this._services.commandExecutor.mutateResource("post", this._links.self, {
851
638
  unique_name: uniqueName,
852
639
  });
853
640
  }
854
641
  return this;
855
642
  }
643
+ /**
644
+ * Load and subscribe to this conversation and do not subscribe to its
645
+ * participants and messages. This or _subscribeStreams will need to be called
646
+ * before any events on conversation will fire.
647
+ * @internal
648
+ */
649
+ async _subscribe() {
650
+ if (this._entityPromise) {
651
+ return this._entityPromise;
652
+ }
653
+ this._entityPromise = this._services.syncClient.document({
654
+ id: this._entityName,
655
+ mode: "open_existing",
656
+ });
657
+ try {
658
+ this._entity = await this._entityPromise;
659
+ this._entity.on("updated", (args) => this._update(args.data));
660
+ this._entity.on("removed", () => this.emit("removed", this));
661
+ this._update(this._entity.data);
662
+ return this._entity;
663
+ }
664
+ catch (err) {
665
+ this._entity = null;
666
+ this._entityPromise = null;
667
+ if (this._services.syncClient.connectionState != "disconnected") {
668
+ Conversation._logger.error("Failed to get conversation object", err);
669
+ }
670
+ Conversation._logger.debug("ERROR: Failed to get conversation object", err);
671
+ throw err;
672
+ }
673
+ }
674
+ /**
675
+ * Load the attributes of this conversation and instantiate its participants
676
+ * and messages. This or _subscribe will need to be called before any events
677
+ * on the conversation will fire. This will need to be called before any
678
+ * events on participants or messages will fire
679
+ * @internal
680
+ */
681
+ async _subscribeStreams() {
682
+ var _a, _b;
683
+ try {
684
+ await this._subscribe();
685
+ Conversation._logger.trace("_subscribeStreams, this.entity.data=", (_a = this._entity) === null || _a === void 0 ? void 0 : _a.data);
686
+ const data = (_b = this._entity) === null || _b === void 0 ? void 0 : _b.data;
687
+ const messagesObjectName = data.messages;
688
+ const rosterObjectName = data.roster;
689
+ await Promise.all([
690
+ this._messagesEntity.subscribe(messagesObjectName),
691
+ this._participantsEntity.subscribe(rosterObjectName),
692
+ ]);
693
+ }
694
+ catch (err) {
695
+ if (this._services.syncClient.connectionState !== "disconnected") {
696
+ Conversation._logger.error("Failed to subscribe on conversation objects", this.sid, err);
697
+ }
698
+ Conversation._logger.debug("ERROR: Failed to subscribe on conversation objects", this.sid, err);
699
+ throw err;
700
+ }
701
+ }
702
+ /**
703
+ * Stop listening for and firing events on this conversation.
704
+ * @internal
705
+ */
706
+ async _unsubscribe() {
707
+ if (this._entity) {
708
+ await this._entity.close();
709
+ this._entity = null;
710
+ this._entityPromise = null;
711
+ }
712
+ return Promise.all([
713
+ this._participantsEntity.unsubscribe(),
714
+ this._messagesEntity.unsubscribe(),
715
+ ]);
716
+ }
717
+ /**
718
+ * Set conversation status.
719
+ * @internal
720
+ */
721
+ _setStatus(status, source) {
722
+ this._dataSource = source;
723
+ if (this._internalState.status === status) {
724
+ return;
725
+ }
726
+ this._internalState.status = status;
727
+ if (status === "joined") {
728
+ this._subscribeStreams().catch((err) => {
729
+ Conversation._logger.debug("ERROR while setting conversation status " + status, err);
730
+ if (this._services.syncClient.connectionState !== "disconnected") {
731
+ throw err;
732
+ }
733
+ });
734
+ return;
735
+ }
736
+ if (this._entityPromise) {
737
+ this._unsubscribe().catch((err) => {
738
+ Conversation._logger.debug("ERROR while setting conversation status " + status, err);
739
+ if (this._services.syncClient.connectionState !== "disconnected") {
740
+ throw err;
741
+ }
742
+ });
743
+ }
744
+ }
745
+ /**
746
+ * Update the local conversation object with new values.
747
+ * @internal
748
+ */
749
+ _update(update) {
750
+ var _a, _b, _c, _d, _e;
751
+ Conversation._logger.trace("_update", update);
752
+ Conversation.preprocessUpdate(update, this.sid);
753
+ const updateReasons = new Set();
754
+ for (const key of Object.keys(update)) {
755
+ const localKey = fieldMappings[key];
756
+ if (!localKey) {
757
+ continue;
758
+ }
759
+ switch (localKey) {
760
+ case fieldMappings.status:
761
+ if (!update.status ||
762
+ update.status === "unknown" ||
763
+ this._internalState.status === update.status) {
764
+ break;
765
+ }
766
+ this._internalState.status = update.status;
767
+ updateReasons.add(localKey);
768
+ break;
769
+ case fieldMappings.attributes:
770
+ if (isEqual__default["default"](this._internalState.attributes, update.attributes)) {
771
+ break;
772
+ }
773
+ this._internalState.attributes = update.attributes;
774
+ updateReasons.add(localKey);
775
+ break;
776
+ case fieldMappings.lastConsumedMessageIndex:
777
+ if (update.lastConsumedMessageIndex === undefined ||
778
+ update.lastConsumedMessageIndex ===
779
+ this._internalState.lastReadMessageIndex) {
780
+ break;
781
+ }
782
+ this._internalState.lastReadMessageIndex =
783
+ update.lastConsumedMessageIndex;
784
+ updateReasons.add("lastReadMessageIndex");
785
+ break;
786
+ case fieldMappings.lastMessage:
787
+ if (this._internalState.lastMessage && !update.lastMessage) {
788
+ delete this._internalState.lastMessage;
789
+ updateReasons.add(localKey);
790
+ break;
791
+ }
792
+ this._internalState.lastMessage =
793
+ this._internalState.lastMessage || {};
794
+ if (((_a = update.lastMessage) === null || _a === void 0 ? void 0 : _a.index) !== undefined &&
795
+ update.lastMessage.index !== this._internalState.lastMessage.index) {
796
+ this._internalState.lastMessage.index = update.lastMessage.index;
797
+ updateReasons.add(localKey);
798
+ }
799
+ if (((_b = update.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp) !== undefined &&
800
+ ((_d = (_c = this._internalState.lastMessage) === null || _c === void 0 ? void 0 : _c.dateCreated) === null || _d === void 0 ? void 0 : _d.getTime()) !==
801
+ update.lastMessage.timestamp.getTime()) {
802
+ this._internalState.lastMessage.dateCreated =
803
+ update.lastMessage.timestamp;
804
+ updateReasons.add(localKey);
805
+ }
806
+ if (isEqual__default["default"](this._internalState.lastMessage, {})) {
807
+ delete this._internalState.lastMessage;
808
+ }
809
+ break;
810
+ case fieldMappings.state:
811
+ const state = update.state || undefined;
812
+ if (state !== undefined) {
813
+ state.dateUpdated = new Date(state.dateUpdated);
814
+ }
815
+ if (isEqual__default["default"](this._internalState.state, state)) {
816
+ break;
817
+ }
818
+ this._internalState.state = state;
819
+ updateReasons.add(localKey);
820
+ break;
821
+ case fieldMappings.bindings:
822
+ if (isEqual__default["default"](this._internalState.bindings, update.bindings)) {
823
+ break;
824
+ }
825
+ this._internalState.bindings = update.bindings;
826
+ updateReasons.add(localKey);
827
+ break;
828
+ default:
829
+ const isDate = update[key] instanceof Date;
830
+ const keysMatchAsDates = isDate &&
831
+ ((_e = this._internalState[localKey]) === null || _e === void 0 ? void 0 : _e.getTime()) === update[key].getTime();
832
+ const keysMatchAsNonDates = !isDate && this[localKey] === update[key];
833
+ if (keysMatchAsDates || keysMatchAsNonDates) {
834
+ break;
835
+ }
836
+ this._internalState[localKey] = update[key];
837
+ updateReasons.add(localKey);
838
+ }
839
+ }
840
+ if (updateReasons.size > 0) {
841
+ this.emit("updated", {
842
+ conversation: this,
843
+ updateReasons: [...updateReasons],
844
+ });
845
+ }
846
+ }
847
+ /**
848
+ * Handle onMessageAdded event.
849
+ */
850
+ _onMessageAdded(message) {
851
+ for (const participant of this._participants.values()) {
852
+ if (participant.identity === message.author) {
853
+ participant._endTyping();
854
+ break;
855
+ }
856
+ }
857
+ this.emit("messageAdded", message);
858
+ }
859
+ /**
860
+ * Set last read message index.
861
+ * @param index New index to set.
862
+ */
863
+ async _setLastReadMessageIndex(index) {
864
+ const result = await this._services.commandExecutor.mutateResource("post", `${this._configuration.links.myConversations}/${this.sid}`, {
865
+ last_read_message_index: index,
866
+ });
867
+ return result.unread_messages_count;
868
+ }
856
869
  }
857
870
  /**
858
871
  * Fired when a participant has joined the conversation.
859
872
  *
860
873
  * Parameters:
861
- * 1. {@link Participant} `participant` - participant that joined the conversation
874
+ * 1. {@link Participant} `participant` - participant that joined the
875
+ * conversation
862
876
  * @event
863
877
  */
864
878
  Conversation.participantJoined = "participantJoined";
@@ -866,7 +880,8 @@ Conversation.participantJoined = "participantJoined";
866
880
  * Fired when a participant has left the conversation.
867
881
  *
868
882
  * Parameters:
869
- * 1. {@link Participant} `participant` - participant that left the conversation
883
+ * 1. {@link Participant} `participant` - participant that left the
884
+ * conversation
870
885
  * @event
871
886
  */
872
887
  Conversation.participantLeft = "participantLeft";
@@ -874,9 +889,12 @@ Conversation.participantLeft = "participantLeft";
874
889
  * Fired when data of a participant has been updated.
875
890
  *
876
891
  * Parameters:
877
- * 1. object `data` - info object provided with the event. It has the following properties:
878
- * * {@link Participant} `participant` - participant that has received the update
879
- * * {@link ParticipantUpdateReason}[] `updateReasons` - array of reasons for update
892
+ * 1. object `data` - info object provided with the event. It has the
893
+ * following properties:
894
+ * * {@link Participant} `participant` - participant that has received the
895
+ * update
896
+ * * {@link ParticipantUpdateReason}[] `updateReasons` - array of reasons
897
+ * for the update
880
898
  * @event
881
899
  */
882
900
  Conversation.participantUpdated = "participantUpdated";
@@ -900,9 +918,11 @@ Conversation.messageRemoved = "messageRemoved";
900
918
  * Fired when data of a message has been updated.
901
919
  *
902
920
  * Parameters:
903
- * 1. object `data` - info object provided with the event. It has the following properties:
921
+ * 1. object `data` - info object provided with the event. It has the
922
+ * following properties:
904
923
  * * {@link Message} `message` - message that has received the update
905
- * * {@link MessageUpdateReason}[] `updateReasons` - array of reasons for update
924
+ * * {@link MessageUpdateReason}[] `updateReasons` - array of reasons for
925
+ * the update
906
926
  * @event
907
927
  */
908
928
  Conversation.messageUpdated = "messageUpdated";
@@ -910,7 +930,8 @@ Conversation.messageUpdated = "messageUpdated";
910
930
  * Fired when a participant has stopped typing.
911
931
  *
912
932
  * Parameters:
913
- * 1. {@link Participant} `participant` - the participant that has stopped typing
933
+ * 1. {@link Participant} `participant` - the participant that has stopped
934
+ * typing
914
935
  * @event
915
936
  */
916
937
  Conversation.typingEnded = "typingEnded";
@@ -918,7 +939,8 @@ Conversation.typingEnded = "typingEnded";
918
939
  * Fired when a participant has started typing.
919
940
  *
920
941
  * Parameters:
921
- * 1. {@link Participant} `participant` - the participant that has started typing
942
+ * 1. {@link Participant} `participant` - the participant that has started
943
+ * typing
922
944
  * @event
923
945
  */
924
946
  Conversation.typingStarted = "typingStarted";
@@ -926,20 +948,28 @@ Conversation.typingStarted = "typingStarted";
926
948
  * Fired when the data of the conversation has been updated.
927
949
  *
928
950
  * Parameters:
929
- * 1. object `data` - info object provided with the event. It has the following properties:
930
- * * {@link Conversation} `conversation` - conversation that has received the update
931
- * * {@link ConversationUpdateReason}[] `updateReasons` - array of reasons for update
951
+ * 1. object `data` - info object provided with the event. It has the
952
+ * following properties:
953
+ * * {@link Conversation} `conversation` - conversation that has received
954
+ * the update
955
+ * * {@link ConversationUpdateReason}[] `updateReasons` - array of reasons
956
+ * for the update
932
957
  * @event
933
958
  */
934
959
  Conversation.updated = "updated";
935
960
  /**
936
- * Fired when the conversation was destroyed or the currently-logged-in user has left private conversation.
961
+ * Fired when the conversation was destroyed or the currently-logged-in user
962
+ * has left private conversation.
937
963
  *
938
964
  * Parameters:
939
965
  * 1. {@link Conversation} `conversation` - conversation that has been removed
940
966
  * @event
941
967
  */
942
968
  Conversation.removed = "removed";
969
+ /**
970
+ * Logger instance.
971
+ */
972
+ Conversation._logger = logger.Logger.scope("Conversation");
943
973
  tslib_es6.__decorate([
944
974
  declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.nonEmptyString, attributes.optionalAttributesValidator),
945
975
  tslib_es6.__metadata("design:type", Function),
@@ -985,9 +1015,8 @@ tslib_es6.__decorate([
985
1015
  tslib_es6.__decorate([
986
1016
  declarativeTypeValidator.validateTypesAsync([
987
1017
  "string",
1018
+ FormData,
988
1019
  declarativeTypeValidator.literal(null),
989
- // Wrapping it into a custom rule is necessary because the FormData class is not available on initialization.
990
- declarativeTypeValidator.custom((value) => [value instanceof FormData, "an instance of FormData"]),
991
1020
  declarativeTypeValidator.objectSchema("media options", {
992
1021
  contentType: declarativeTypeValidator.nonEmptyString,
993
1022
  media: declarativeTypeValidator.custom((value) => {
@@ -1027,7 +1056,7 @@ tslib_es6.__decorate([
1027
1056
  tslib_es6.__metadata("design:returntype", Promise)
1028
1057
  ], Conversation.prototype, "updateAttributes", null);
1029
1058
  tslib_es6.__decorate([
1030
- declarativeTypeValidator.validateTypesAsync(["string"]),
1059
+ declarativeTypeValidator.validateTypesAsync("string"),
1031
1060
  tslib_es6.__metadata("design:type", Function),
1032
1061
  tslib_es6.__metadata("design:paramtypes", [String]),
1033
1062
  tslib_es6.__metadata("design:returntype", Promise)